Come conservare: backup giornalieri per una settimana, settimanali per un mese, mensili per un anno e successivamente annuali


14

Devo eseguire il backup dei dati e configurare i file su questo server ogni giorno. Devo mantenere:

  • backup giornalieri per una settimana
  • backup settimanali per un mese
  • backup mensili per un anno
  • backup annuali successivi

Tutto ciò realizzato tramite uno script di shell eseguito quotidianamente da cron.

Ecco come dovrebbero apparire i file di backup dopo 10 anni di esecuzione:

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
... il mio suggerimento normale sarebbe "Usa Bacula " (o qualche altro software di backup in grado di gestire la conservazione e la rotazione per te) :-)
voretaq7,

1
questa domanda mi ha fatto scrivere cronicle < github.com/Kraymer/cronicle > perché la risposta accettata ha l'ovvio difetto di duplicare i backup nelle cartelle giornaliere / settimanali / ecc. cronicle si basa su collegamenti simbolici e si occupa della rotazione, eliminando i file sottostanti quando nessuna cartella contiene collegamenti simbolici che puntano ad esso.
kraymer,

Risposte:


29

Stai seriamente progettando troppo questo. Male.

Ecco alcuni pseudocodici:

  • Ogni giorno:
    • fare un backup, mettere in dailydirectory
    • rimuovere tutto tranne gli ultimi 7 dailybackup
  • Ogni settimana:
    • fare un backup, mettere in weeklydirectory
    • rimuovere tutto tranne gli ultimi 5 weeklybackup
  • Ogni mese:
    • fare un backup, mettere nella monthlydirectory
    • rimuovere tutto tranne gli ultimi 12 monthlybackup
  • Ogni anno:
    • fare un backup, mettere nella yearlydirectory

La quantità di logica che devi implementare è più o meno la stessa, eh? BACIO.

Questo sembra più facile:

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

Oppure, per numero di file anziché per età:

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

In realtà non ho directory separate. È stato scritto per scaricare i file in un bucket S3. Una volta che tutto è in un unico posto, la quantità totale di logica che è necessario implementare è praticamente la stessa, indipendentemente da come si procede.
Florin Andrei,

5
Evidentemente non lo è.
MadHatter,

6

Se vuoi solo conservare, ad esempio, 8 backup giornalieri e 5 backup settimanali (ogni domenica), funziona così:

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

Ad oggi (10-11-2014), ciò produrrà:

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

Come esercizio lasciato a te, devi solo eliminare tutti i file di backup i cui nomi non compaiono keepnell'array.

Se vuoi conservare anche 13 backup mensili (prima domenica di ogni mese) e 6 backup annuali (prima domenica di ogni anno), le cose diventano un po 'più complicate:

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

Ad oggi (10-11-2014), ciò produrrà:

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

Come sopra, elimina tutti i file di backup non presenti in questo array.


Bello, e come posso fare rm /dir/*.* except keep[@]?
data

0

Come indicato in un commento, in genere è consigliabile delegare l'attività di gestione dei backup a un software di gestione dei backup.

Ma qui è la logica in bash per eliminare i backup più vecchi secondo le vostre esigenze

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

Codice PHP che mostra quali file rimarranno dopo l'esecuzione per 3520 giorni

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
)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.