Вопрос: Как сохранить: ежедневное резервное копирование на неделю, еженедельно на месяц, ежемесячно на год и ежегодно после этого


Мне нужно ежедневно копировать данные и файлы конфигурации на этом сервере. Мне нужно сохранить:

  • ежедневное резервное копирование в течение недели
  • недельное резервное копирование на месяц
  • ежемесячные резервные копии на год
  • годовых резервных копий после этого

Все это выполняется через скрипт оболочки, выполняемый ежедневно из 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

13
2018-02-12 21:10


Источник


... мое нормальное предложение было бы «Использовать Bacula»(или другое программное обеспечение резервного копирования, которое может обрабатывать удержание и ротацию для вас) :-) - voretaq7
этот вопрос заставил меня написать хронику <github.com/Kraymer/cronicle>; потому что принятый ответ имеет очевидный дефект дублирования резервных копий в ежедневных / еженедельных / etc папках. cronicle опирается на символические ссылки и заботится о ротации, удаляя базовые файлы, когда ни одна из папок не содержит символических ссылок, указывающих на нее. - kraymer


Ответы:


Вы серьезно переделываете это. Плохо.

Вот несколько псевдокодов:

  • Каждый день:
    • сделать резервную копию, вставить 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

25
2018-02-12 21:21



На самом деле у меня нет отдельных каталогов. Это было написано, чтобы сбрасывать файлы в ведро S3. Когда все будет в одном месте, общий объем логики, который вам нужно реализовать, примерно одинаковый, независимо от того, как вы это делаете. - Florin Andrei
По-видимому, это не так. - MadHatter


Если вы просто хотите сохранить, например, 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

Как и выше, просто удалите все файлы резервных копий, которые не найдены в этом массиве.


6
2017-11-10 19:01



Приятно, и как мне это сделать? rm /dir/*.* except keep[@]? - takeshin