Як зберегти: щоденні резервні копії протягом тижня, тиждень протягом місяця, щомісяця протягом року та щорічно після цього


14

Мені потрібно щодня створювати резервні копії даних та конфігурувати файли на цьому сервері. Мені потрібно зберегти:

  • щоденне резервне копіювання на тиждень
  • щотижневі резервні копії на місяць
  • щомісячне резервне копіювання на рік
  • щорічні резервні копії після цього

Все це виконується за допомогою сценарію оболонки, щодня виконується з 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
... моєю звичайною пропозицією було б "Використовувати Bacula " (або якесь інше програмне забезпечення для резервного копіювання, яке може працювати для утримання та обертання) :-)
voretaq7

1
це запитання змусило мене написати хроніку < github.com/Kraymer/cronicle >, оскільки прийнята відповідь має очевидний недолік дублювання резервних копій у папках щодня / тиждень / тощо. літопис покладається на символьні посилання та піклується про обертання, видаляючи базові файли, коли жодна папка не містить вказівки на неї.
краймер

Відповіді:


29

Ви серйозно переробите це. Погано.

Ось псевдокод:

  • Щодня:
    • зробити резервну копію, ввести в dailyкаталог
    • видаліть усе, крім останніх 7 dailyрезервних копій
  • Кожного тижня:
    • зробити резервну копію, ввести в weeklyкаталог
    • видаліть усе, крім останніх 5 weeklyрезервних копій
  • Щомісяця:
    • зробити резервну копію, ввести в monthlyкаталог
    • видаліть усе, крім останніх 12 monthlyрезервних копій
  • Щороку:
    • зробити резервну копію, ввести в yearlyкаталог

Обсяг логіки, який ви повинні реалізувати, приблизно однаковий, так? KISS.

Це виглядає простіше:

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. Після того, як все стоїть на одному місці, загальна кількість логіки, яку потрібно реалізувати, приблизно однакова, незалежно від того, як ви це зробите.
Флорін Андрій

5
Очевидно, що це не так.
MadHatter

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

Як зазначено в коментарі, зазвичай найкраще делегувати завдання управління резервними копіями програмним забезпеченням для управління резервними копіями.

Але ось логіка в баші для видалення старих резервних копій відповідно до вашої вимоги

#!/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

PHP-код, який показує, які файли залишаться після запуску протягом 3520 днів

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
)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.