如何保持:一周的每日备份,一个月的每周备份,一年的每月备份以及之后的每年备份

我需要每天在这台服务器上备份数据和configuration文件。 我需要保持:

  • 每日备份一周
  • 每周备份一个月
  • 每月备份一年
  • 之后的年度备份

所有这些都是通过每天从cron运行的shell脚本完成的。

这是在运行10年后备份文件的样子:

blog-20050103.tar.bz2 blog-20060102.tar.bz2 blog-20070101.tar.bz2 blog-20080107.tar.bz2 blog-20090105.tar.bz2 blog-20100104.tar.bz2 blog-20110103.tar.bz2 blog-20120102.tar.bz2 blog-20130107.tar.bz2 blog-20130902.tar.bz2 blog-20131007.tar.bz2 blog-20131104.tar.bz2 blog-20131202.tar.bz2 blog-20140106.tar.bz2 blog-20140203.tar.bz2 blog-20140303.tar.bz2 blog-20140407.tar.bz2 blog-20140505.tar.bz2 blog-20140602.tar.bz2 blog-20140707.tar.bz2 blog-20140728.tar.bz2 blog-20140804.tar.bz2 blog-20140811.tar.bz2 blog-20140816.tar.bz2 blog-20140817.tar.bz2 blog-20140818.tar.bz2 blog-20140819.tar.bz2 blog-20140820.tar.bz2 blog-20140821.tar.bz2 blog-20140822.tar.bz2 

你严重过度工程这一点。 厉害。

这是一些伪代码:

  • 每天:
    • 做一个备份,放入daily目录
    • 除了最近7次daily备份之外,删除所有内容
  • 每周:
    • 做一个备份,放入weekly目录
    • 删除除最后5个weekly备份以外的所有内容
  • 每个月:
    • 做一个备份,放入monthly目录
    • 除去最近12个monthly备份,删除所有内容
  • 每年:
    • 备份,放入yearly目录

你必须执行的逻辑数量大致相同,呃? 吻。

这看起来更容易:

 s3cmd ls s3://backup-bucket/daily/ | \ awk '$1 < "'$(date +%F -d '1 week ago')'" {print $4;}' | \ xargs --no-run-if-empty s3cmd del 

或者,通过文件数量而不是年龄:

 s3cmd ls s3://backup-bucket/daily/ | \ awk '$1 != "DIR"' | \ sort -r | \ awk 'NR > 7 {print $4;}' | \ xargs --no-run-if-empty s3cmd del 

例如,如果您只想保留8个每日备份和5个每周(每个星期天)备份,则可以这样工作:

 for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done echo ${!keep[@]} 

截至今天(2014-11-10),这将输出:

 20141012 20141019 20141026 20141102 20141103 20141104 20141105 20141106 20141107 20141108 20141109 20141110 

作为一个锻炼留给你,你只需要删除所有的名字没有出现在keep数组的备份文件。

如果你想保持每月13个月的备份(每个月的第一个周日)和每年6个备份(每年的第一个周日),事情会变得更复杂一点:

 for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done for i in {0..12}; do DW=$(($(date +%-W)-$(date -d $(date -d "$(date +%Y-%m-15) -$i month" +%Y-%m-01) +%-W))) for (( AY=$(date -d "$(date +%Y-%m-15) -$i month" +%Y); AY < $(date +%Y); AY++ )); do ((DW+=$(date -d $AY-12-31 +%W))) done ((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++)) done for i in {0..5}; do DW=$(date +%-W) for (( AY=$(($(date +%Y)-i)); AY < $(date +%Y); AY++ )); do ((DW+=$(date -d $AY-12-31 +%W))) done ((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++)) done echo ${!keep[@]} 

截至今天(2014-11-10),这将输出:

 20090104 20100103 20110102 20120101 20130106 20131103 20131201 20140105 20140202 20140302 20140406 20140504 20140601 20140706 20140803 20140907 20141005 20141012 20141019 20141026 20141102 20141103 20141104 20141105 20141106 20141107 20141108 20141109 20141110 

和上面一样,只要删除在这个数组中找不到的所有备份文件。