保持方法:1週間の毎日のバックアップ、1か月の毎週、1年間の毎月、およびその後の毎年のバックアップ


14

このサーバー上のデータと構成ファイルを毎日バックアップする必要があります。私は維持する必要があります:

  • 1週間の毎日のバックアップ
  • 1週間の毎週のバックアップ
  • 1年間の月次バックアップ
  • その後の年間バックアップ

これらはすべて、cronから毎日実行されるシェルスクリプトによって実現されます。

これは、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

9
...私の通常の提案は「Use Bacula」(または保持とローテーションを処理できる他のバックアップソフトウェア)です:
voretaq7 14

1
受け入れられた答えには、バックアップを毎日/毎週/などのフォルダーに複製するという明らかな欠陥があるため、この質問により、私はクロニクル< github.com/Kraymer/cronicle >を作成しました。cronicleはシンボリックリンクに依存し、回転を処理し、それを指すシンボリックリンクが含まれるフォルダーがない場合、基礎となるファイルを削除します。
クレイマー

回答:


29

あなたはこれを真剣に過剰設計しています。ひどく。

疑似コードは次のとおりです。

  • 毎日:
    • バックアップを作成し、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

実際、個別のディレクトリはありません。ファイルをS3バケットにダンプするために作成されました。すべてを1か所にまとめると、どのように実行しても、実装する必要のあるロジックの合計量はほぼ同じになります。
フローリンアンドレイ14

5
明らかにそうではありません。
MadHatter 14

6

たとえば、毎日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-arrayに表示されないすべてのバックアップファイルを削除するだけです。

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

上記と同じように、この配列にないすべてのバックアップファイルを削除します。


いいですね、どうすればいいですrm /dir/*.* except keep[@]か?
武心

0

コメントで述べたように、通常、バックアップを管理するタスクをバックアップ管理ソフトウェアに委任するのが最善です。

ただし、要件に応じて古いバックアップを削除するためのbashのロジックは次のとおりです。

#!/bin/sh

delete() {
    echo "Deleting $1"
}

DOW=$(date +%u)

if [ $DOW -eq 1 ]; then
    DATE_DAY=$(date -d "-28 days" +"%d")
    if [ $DATE_DAY -gt 7 ]; then
        DATE=$(date -d "-28 days" +"%Y-%m-%d")
        delete $DATE
    fi

    DATE_DAY=$(date -d "-364 days" +"%d")
    DATE_MONTH=$(date -d "-364 days" +"%m")
    if [ $DATE_DAY -le 7 ] && [ $DATE_MONTH -gt 1 ]; then
        DATE=$(date -d "-364 days" +"%Y-%m-%d")
        delete $DATE
    fi
else
    DATE=$(date -d "-7 days" +"%Y-%m-%d")
    delete $DATE
fi

3520日間実行した後に残るファイルを示すPHPコード

https://ideone.com/n2ymQy

Array
(
    [0] => 2005-01-03
    [1] => 2006-01-02
    [2] => 2007-01-01
    [3] => 2008-01-07
    [4] => 2009-01-05
    [5] => 2010-01-04
    [6] => 2011-01-03
    [7] => 2012-01-02
    [8] => 2013-01-07
    [9] => 2013-09-02
    [10] => 2013-10-07
    [11] => 2013-11-04
    [12] => 2013-12-02
    [13] => 2014-01-06
    [14] => 2014-02-03
    [15] => 2014-03-03
    [16] => 2014-04-07
    [17] => 2014-05-05
    [18] => 2014-06-02
    [19] => 2014-07-07
    [20] => 2014-07-28
    [21] => 2014-08-04
    [22] => 2014-08-11
    [23] => 2014-08-16
    [24] => 2014-08-17
    [25] => 2014-08-18
    [26] => 2014-08-19
    [27] => 2014-08-20
    [28] => 2014-08-21
    [29] => 2014-08-22
)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.