Cómo mantener: copias de seguridad diarias durante una semana, semanalmente durante un mes, mensualmente durante un año y anualmente después de eso

14

Necesito hacer una copia de seguridad de los datos y los archivos de configuración en este servidor, diariamente. Necesito mantener:

  • copias de seguridad diarias durante una semana
  • copias de seguridad semanales durante un mes
  • respaldos mensuales por un año
  • copias de seguridad anuales después de eso

Todo esto se logra a través de un script de shell que se ejecuta diariamente desde cron.

Así es como deberían verse los archivos de respaldo después de 10 años de ejecución:

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
fuente
99
... mi sugerencia normal sería "Usar Bacula " (o algún otro software de respaldo que pueda manejar la retención y la rotación por usted) :-)
voretaq7
1
esta pregunta me hizo escribir cronicle < github.com/Kraymer/cronicle > porque la respuesta aceptada tiene el defecto obvio de duplicar copias de seguridad en las carpetas diarias / semanales / etc. cronicle se basa en enlaces simbólicos y se encarga de la rotación, eliminando archivos subyacentes cuando ninguna carpeta contiene enlaces simbólicos que apuntan a él.
kraymer

Respuestas:

29

Estás sobre-diseñando esto en serio. Mal.

Aquí hay un pseudocódigo:

  • Todos los días:
    • hacer una copia de seguridad, poner en el dailydirectorio
    • eliminar todo menos las últimas 7 dailycopias de seguridad
  • Cada semana:
    • hacer una copia de seguridad, poner en el weeklydirectorio
    • eliminar todo menos las últimas 5 weeklycopias de seguridad
  • Cada mes:
    • hacer una copia de seguridad, poner en el monthlydirectorio
    • eliminar todo menos las últimas 12 monthlycopias de seguridad
  • Todos los años:
    • hacer una copia de seguridad, poner en el yearlydirectorio

La cantidad de lógica que tienes que implementar es casi la misma, ¿eh? BESO.

Esto parece más fácil:

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

O, por recuento de archivos en lugar de edad:

s3cmd ls s3://backup-bucket/daily/ | \
    awk '$1 != "DIR"' | \
    sort -r | \
    awk 'NR > 7 {print $4;}' | \
    xargs --no-run-if-empty s3cmd del
MikeyB
fuente
En realidad no tengo directorios separados. Fue escrito para volcar archivos en un cubo S3. Una vez que todo está en un solo lugar, la cantidad total de lógica que necesita implementar es casi la misma, sin importar cómo lo haga.
Florin Andrei
55
Evidentemente no lo es.
MadHatter
6

Si solo desea conservar, por ejemplo, 8 copias de seguridad diarias y 5 copias de seguridad semanales (todos los domingos), funciona así:

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

A partir de hoy (10/11/2014), esto generará:

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

Como ejercicio que le queda, solo tiene que eliminar todos los archivos de copia de seguridad cuyos nombres no aparecen en la keepmatriz.

Si desea conservar 13 copias de seguridad mensuales (primer domingo de cada mes) y 6 copias de seguridad anuales (primer domingo de cada año), las cosas se vuelven un poco más complicadas:

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

A partir de hoy (10/11/2014), esto generará:

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

Igual que el anterior, simplemente elimine todos los archivos de copia de seguridad que no se encuentran en esta matriz.

Powpow
fuente
Bien, y como lo hago rm /dir/*.* except keep[@]?
takeshin
0

Como se menciona en un comentario, normalmente es mejor delegar la tarea de administrar copias de seguridad a un software de administración de copias de seguridad.

Pero aquí está la lógica en bash para eliminar copias de seguridad anteriores según sus requisitos

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

Código PHP que muestra qué archivos permanecerán después de ejecutarse durante 3520 días

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
fuente