domenica, aprile 22, 2007

Backup incrementale con Rsync e Crontab

Ho ho modificato e migliorato uno script trovato in rete (ho perso la fonte ... fonte originale) per l'esecuzione di backup incrementali dei nostri preziosissimi dati.

Questo script permette di archiviare un determinato numero di backup in relativamente molto poco spazio.

Inoltre questo metodo di esecuzione dei backup si è rilevato estremamente veloce.

La chiave di tutto è l'uso del comando "cp" con l'opzione "-l" (che esegue collegamenti fisici => "hard link" piuttosto che copie dei file) con cui copio l'ultimo backup che viene sincronizzato con le ultime modifiche con "rsync".

Per ulteriori dettagli vi rimando allo script stesso:
#!/bin/bash

# ========== CONFIGURATION ============
# directory dove appoggiare i backup
DIR_BKP="/mnt/backup1"
# file con i pattern da escludere dal backup
EXCLUDES="/usr/local/etc/backup_dati_exclude"
# nr di giorni da consevare
NDAY=14
# prefisso della directory del backup
PRE="backup_dati"
# directory da backuppare
TARGET="/home"
# ====================================

# ====================================
echo "=> Fase 1 ($(date '+%d-%m-%Y %H:%M')): Cambio \
permessi e rimozione del backup piu' vecchio <="
# cambio permessi
chmod -R 700 "$DIR_BKP/$PRE.*"

# Viene eseguita solo alla prima esecuzione
if [ -e "$DIR_BKP/$PRE.0" ]; then
echo "*"
else
echo "Prima esecuzione !!!"
mkdir "$DIR_BKP/$PRE.0"
fi;

# rimozione del backup più vecchio
if [ -d "$DIR_BKP/$PRE.$NDAY" ] ; then
echo " rm -rf $DIR_BKP/$PRE.$NDAY"
rm -rf "$DIR_BKP/$PRE.$NDAY"
fi

# ====================================
echo "=> Fase 2 ($(date '+%d-%m-%Y %H:%M')): Shifto \
di una unita' i backup esistenti <="

while [ $NDAY -gt 1 ]; do
NDAY2=$(($NDAY-1))

if [ -d "$DIR_BKP/$PRE.$NDAY2" ] ; then
echo " mv $PRE.$NDAY2 $PRE.$NDAY"
mv "$DIR_BKP/$PRE.$NDAY2 $DIR_BKP/$PRE.$NDAY"
fi;

NDAY=$NDAY2;
done

# ====================================
echo "=> Fase 3 ($(date '+%d-%m-%Y %H:%M')): Creo \
hard link del backup piu' recente <="

if [ -d "$DIR_BKP/$PRE.0" ] ; then
echo "cp -al $PRE.0 $PRE.1"
cp -al "$DIR_BKP/$PRE.0 $DIR_BKP/$PRE.1"
fi;

# ====================================
echo "=> Fase 4 ($(date '+%d-%m-%Y %H:%M')): Eseguo \
il backup <="
# Verifica se c'è il file per le esclusioni
if [ -r $EXCLUDES ] ; then
EXCL="--delete-excluded --exclude-from=$EXCLUDES"
else
EXCL=""
fi;

#Comando di backup
rsync -av --delete $EXCL $TARGET "$DIR_BKP/$PRE.0"

echo "=> Fase 5 ($(date '+%d-%m-%Y %H:%M')): Cambio \
i permesi in sola lettura <="
chmod -R 500 "$DIR_BKP/$PRE.*"

# Aggiornamento della data della cartella dell'ultimo
# backup per riflettere la data e l'ora del backup
# FORSE NON SERVE !!!
touch "$DIR_BKP/$PRE.0"

# ====================================
echo "=> FINE ($(date '+%d-%m-%Y %H:%M')) <="


Per automatizzare il l'esecuzione del backup ad intervalli specifici si può usare crontab.
Ad esempio per eseguire il backup alle ore 23:00 ogni giorno dal Lunedì al Venerdì basta eseguire:
sudo crontab -e
ed aggiungere in un'unica riga questo:

0 23 * * 1-5 /usr/local/sbin/backup.sh |
mail mail@xyz.it -s
"Backup del $(/bin/date '+\%d-\%m-\%Y \%H:\%M')"


Spero possa essere utile a qualcuno.
Ciao e alla prossima.

12 commenti:

angelo ha detto...

Sei decisamente uno dei migliori blogger sulla piazza

daniele ha detto...

@angelo
... così divento rosso ...
Spero di riuscire a mantenere nel futuro questo livello, e che la benzina non finisca presto :)
Ciao e grazie!

Luca ha detto...

veramente molto utile...appena sistemo le cose in feisty lo provo!

Angelo IWM ha detto...

Complimenti per le modifiche :)
Credo che tu sia partito dal mio post qui http://bglugvs.web3king.com/?p=36

Provero' le tue modifiche e aggiornero' anche il mio post

Ciao
Angelo

Anonimo ha detto...

Ciao e complimenti per lo script.
Mi viene pero' un piccolo dubbio a proposito del "cp -l" che usi.Se ogni copia del backup punta agli stessi file, quando rsync modifica la copia ".0" tutte le altre vengono automaticamente modificate ( il file x è sempre lo stesso, solo referenziato il piu' dir ).
Questo mi sembra annulli totalmente l'utilità di avere 14 giorni di backup, non sei d'accordo?
grazie e ciao

daniele ha detto...

@Angelo
Confermo che SI, sono partito dal tuo script e dalla tua fantastica idea dell'uso di cp -l + rsync.
Grazie infinite per quel post e quello script. Mi sono stati infinitamente utili.
Ciao e ancora grazie

daniele ha detto...

@Anonimo
No! Questo perchè un file può avere da 1 (praticamente quando non ci sono altri collegamenti fisici: situazione standard) ad infiniti collegamenti fisici (c'è un limite ma ora non saprei dirvi).

Rsync quando trova modifiche cancella solamente il collegamento fisico, non il file, e lo sostituisce con il file modificato.

Il file viene cancellato solamente quando viene cancellato l'ultimo collegamento fisico.

Anonimo ha detto...

ciao, sul mio sistema ho dovuto cambiare
chmod -R 700 "$DIR_BKP/$PRE.*"
in
chmod -R 700 "$DIR_BKP/$PRE."*
poichè mi interpretava l'* come carattere non jolly
Michele

Anonimo ha detto...

${PRE}*

man bash...

ppierluigi

allegro ha detto...

cp -al backup_dati.0 backup_dati.1
cp: manca l'operando per il file di destinazione dopo "/media/Backup2/Backup/backup_dati.0 /media/Backup2/Backup/backup_dati.1"
però lo script va a buon fine
quale è il problema?
ciao

naspemls ha detto...

io ho risolto togliendo gli apici dai comandi

Francesco Spegni ha detto...

ho notato che cosi` com'e` invocato, rsync ricopia tutti i file che hanno mutato i diritti d'accesso perche` li "vede" come modificati.

leggendo questo post ho deciso di richiamare rsync con i flag:

rsync -rltzuv --delete ...

e mi pare funzionare bene. spero possa essere d'aiuto a chi cercasse informazioni in futuro. e grazie per l'utile script di backup, che si e` dimostrato un ottimo punto di partenza :)