Jak zachować: codzienne kopie zapasowe przez tydzień, co tydzień przez miesiąc, co miesiąc przez rok, a następnie co roku

14

Muszę codziennie tworzyć kopie zapasowe danych i plików konfiguracyjnych na tym serwerze. Muszę zachować:

  • codzienne kopie zapasowe przez tydzień
  • cotygodniowe kopie zapasowe przez miesiąc
  • miesięczne kopie zapasowe przez rok
  • następnie roczne kopie zapasowe

Wszystko to osiągnięto poprzez skrypt powłoki uruchamiany codziennie z crona.

Tak powinny wyglądać pliki kopii zapasowej po 10 latach działania:

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
Florin Andrei
źródło
9
... moją normalną sugestią byłoby „Użyj Baculi ” (lub innego oprogramowania do tworzenia kopii zapasowych, które może obsługiwać przechowywanie i rotację dla Ciebie) :-)
voretaq7
1
to pytanie zmusiło mnie do napisania cronicle < github.com/Kraymer/cronicle >, ponieważ przyjęta odpowiedź ma oczywistą wadę polegającą na powielaniu kopii zapasowych w folderach dziennych / tygodniowych / etc. cronicle korzysta z dowiązań symbolicznych i dba o obrót, usuwając pliki leżące u podstaw, gdy żaden folder nie zawiera dowiązań symbolicznych do niego wskazujących.
kraymer

Odpowiedzi:

29

Poważnie nadużywacie tego. Źle.

Oto pseudokod:

  • Codzienny:
    • wykonaj kopię zapasową, umieść w dailykatalogu
    • usuń wszystko oprócz ostatnich 7 dailykopii zapasowych
  • Co tydzień:
    • wykonaj kopię zapasową, umieść w weeklykatalogu
    • usuń wszystko oprócz ostatnich 5 weeklykopii zapasowych
  • Każdego miesiąca:
    • wykonaj kopię zapasową, umieść w monthlykatalogu
    • usuń wszystko oprócz ostatnich 12 monthlykopii zapasowych
  • Każdego roku:
    • wykonaj kopię zapasową, umieść w yearlykatalogu

Ilość logiki, którą musisz zastosować, jest prawie taka sama, co? POCAŁUNEK.

Wygląda to łatwiej:

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

Lub według liczby plików zamiast wieku:

s3cmd ls s3://backup-bucket/daily/ | \
    awk '$1 != "DIR"' | \
    sort -r | \
    awk 'NR > 7 {print $4;}' | \
    xargs --no-run-if-empty s3cmd del
MikeyB
źródło
Tak naprawdę nie mam osobnych katalogów. Został napisany, aby zrzucić pliki do segmentu S3. Gdy wszystko znajdzie się w jednym miejscu, całkowita logika, którą musisz wdrożyć, jest prawie taka sama, bez względu na to, jak sobie z tym poradzisz.
Florin Andrei
5
Najwyraźniej tak nie jest.
MadHatter
6

Jeśli chcesz na przykład przechowywać 8 codziennych kopii zapasowych i 5 tygodniowych (w każdą niedzielę) kopii zapasowych, działa to tak:

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[@]}

Na dzień dzisiejszy (10.11.2014) spowoduje to:

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

Jako ćwiczenie pozostawiasz do usunięcia, po prostu musisz usunąć wszystkie pliki kopii zapasowych, których nazwy nie pojawiają się w keep-array.

Jeśli chcesz zachować 13 miesięcznych kopii zapasowych (pierwsza niedziela każdego miesiąca) i 6 rocznych kopii zapasowych (pierwsza niedziela każdego roku), sprawy stają się nieco bardziej skomplikowane:

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[@]}

Na dzień dzisiejszy (10.11.2014) spowoduje to:

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

Tak jak powyżej, po prostu usuń wszystkie pliki kopii zapasowej, których nie ma w tej tablicy.

powpow
źródło
Fajnie i jak mam to zrobić rm /dir/*.* except keep[@]?
trwa
0

Jak wspomniano w komentarzu, zwykle najlepiej jest przekazać zadanie zarządzania kopiami zapasowymi oprogramowaniu do zarządzania kopiami zapasowymi.

Ale oto logika w bash do usuwania starszych kopii zapasowych zgodnie z wymaganiami

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

Kod PHP pokazujący, które pliki pozostaną po uruchomieniu przez 3520 dni

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
)
Joyce Babu
źródło