Afin d'optimiser le temps et le volumes de mes sauvegardes j'ai réfléchi à différentes solutions. Jusqu'à présent j'utilisais rsync via un petit script maison et puis j'ai fais des recherches sur rdiff-backup pensant que celui-ci transférait uniquement les blocs de fichier modifié alors que rsync transférait tout la totalité du fichier modifié. Grosse erreur, tout deux transfert uniquement les blocs de fichiers modifier. Donc comment optimiser un petit peu tout ça ?
Grâce au journaux de linuxfr j'ai découvert l'option --link-dest de rsync.
Mise à jour :
- 15/04/2012 : possibilité d'avoir plusieurs sources de sauvegardes.
- 02/04/2012 : mise à jour de la gestion des dates.
- 27/03/2012 : gestion de la sauvegarde sur ftp d'ovh ou HubiC.
L'idée de départ est d'avoir une gestion de version de backup sur x jours, c'est ce qu'on appel la rétention. Le problème dans ce cas va être le volume de données à gérer. Pour contourner ce problème Linux dispose des "liens en dur" (hard link). Pas forcement créé pour au début mais vachement pratique quand même.
Imaginons :
- le répertoire /home/flipflip comme répertoire à sauvegarder
- le répertoire /mnt/backup comme répertoire de stockage des sauvegardes
#!/bin/bash # +-------------------------------- # | Définition des répertoires # +-------------------------------- BASETARGET="/media/backup" TARGET="${BASETARGET}/sauvegarde" # Tableau des répertoires à sauvegarder SOURCE[0]="/home/USERS/Images" SOURCE[1]="/home/USERS/Modèles" # +-------------------------------- # | mode de montage de target # | valeur possible : ftp, dav # +-------------------------------- MODE="dav" # +-------------------------------- # | url du partage webdav # | voir : http://www.blogoflip.fr/?ovh-hubic-en-ligne-de-commande # +-------------------------------- URLDAV="https://cloudnas1.ovh.com/6z9affd86ee8486468b17be15938b82a/" # +-------------------------------- # | Information méthode ftp # | voir : http://www.blogoflip.fr/?sauvegarde-sur-le-ftp-d-ovh # +-------------------------------- USERFTP= PASSFTP= HOTEFTP= RETENTION=5 # Les répertoires de sauvegardes ont pour structure YYYY-MM-DD OLDDATE=`date +%Y-%m-%d --date '1 day ago'` DAYDATE=`date +%Y-%m-%d` remove_old() { # Gère la rétention des backups LS=`ls -d ${TARGET}/2* | sort | head --lines=-${RETENTION} | xargs rm -rf` if [ ${?} -ne 0 ] then echo "Une erreur c'est produite pendant la rotation des backup" exit 1 fi } go_backup() { # La partie intéressante est --link-dest # Ce paramêtre créé automatiquement des liens hard si le fichier est identique entre OLD et JOUR for BACKUP in "${SOURCE[@]}" do rsync -ah --progress --delete-after --stats --no-owner --no-group --safe-links --link-dest=${TARGET}/${OLDDATE} ${BACKUP} ${TARGET}/${DAYDATE}/ done } mount_dav() { if [ ! -d $HOME/.davfs/secrets ] then mount -t davfs $URLDAV $BASETARGET if [ $? -ne 0 ] then echo "Erreur pendant le montage" exit 1 fi else echo "Le fichier $HOME/.davfs/secret n'existe pas" echo "Créer le fichier secrets contenant :" echo "http://URLWEBDAV login password" exit 1 fi } mount_ftp () { curlftpfs#$USERFTP:$PASSFTP@$HOTEFTP $BASETARGET if [ $? -ne 0 ] then echo "Une erreur c'est produite pendant le montage" exit 1 fi } umount_backup () { umount $BASETARGET if [ $? -ne 0 ] then echo "Erreur pendant le demontage de $BASETARGET" exit 1 fi } case $MODE in dav) mount_dav ;; ftp) mount_ftp ;; *) echo "Erreur de paramétrage du mode" ;; esac if [ -d ${TARGET}/${DAYDATE} ] then echo "Le répertoire ${DAYDATE} existe déjà" go_backup else go_backup remove_old fi umount_backup exit 0
- TARGET est le répertoire de stockage des sauvegardes;
- SOURCE est le répertoire à sauvegarde.
JOUR, MOIS, ANNEE vont nous permettre de créer une structure de répertoires sous la forme YYYY-MM-DD. RETENTION correspond au nombre de jours de sauvegarde à conserver en plus du jour de lancement de la sauvegarde.
Le script est découpé en deux fonctions :
- remove_old qui supprime les anciennes sauvegardes;
- go_backup qui lance la sauvegarde.
Ensuite une condition toute bête qui test si le répertoire du jour de la sauvegarde existe dans ce cas il lance uniquement la sauvegarde sinon il lance la rotation des sauvegardes et la sauvegarde. Cette condition empêche la suppression des anciennes sauvegardes dans le cas ou vous lancez plusieurs fois par jour la sauvegarde.
Mise en situation
Je suis le 20 du mois, je lance pour la première fois la sauvegarde, mon répertoire SOURCE contient :
drwx------ 2 flipflip flipflip 4096 2 nov. 2010 dir1 -rwx------ 1 flipflip flipflip 0 20 janv. 12:10 fic -rwx------ 1 flipflip flipflip 0 2 nov. 2010 fic1 -rwx------ 1 flipflip flipflip 0 2 nov. 2010 fic2
Et pour le moment TARGET est vide, je lance la sauvegarde :
ls: impossible d'accéder à /mnt/backup/2*: Aucun fichier ou dossier de ce type --link-dest arg does not exist: /mnt/backup/2012-01-19 cd+++++++++ ./ >f+++++++++ fic >f+++++++++ fic1 >f+++++++++ fic2 cd+++++++++ dir1/ >f+++++++++ dir1/ficdir1 >f+++++++++ dir1/ficdir2 Number of files: 7 Number of files transferred: 5 Total file size: 0 bytes Total transferred file size: 0 bytes Literal data: 0 bytes Matched data: 0 bytes File list size: 132 File list generation time: 0.001 seconds File list transfer time: 0.000 seconds Total bytes sent: 340 Total bytes received: 113 sent 340 bytes received 113 bytes 906.00 bytes/sec total size is 0 speedup is 0.00
Les deux premiers messages sont normaux puisque c'est la première fois qu'on le lance, le répertoire TARGET contient maintenant :
drwx------ 3 flipflip flipflip 4096 20 janv. 12:10 2012-01-20
Et un ls -l dans 2012-01-20 donne :
drwx------ 2 flipflip flipflip 4096 2 nov. 2010 dir1 -rwx------ 1 flipflip flipflip 0 20 janv. 12:10 fic -rwx------ 1 flipflip flipflip 0 2 nov. 2010 fic1 -rwx------ 1 flipflip flipflip 0 2 nov. 2010 fic2
Jusque la tout va bien. Le lendemain arrive donc nous somme le 21, je travaille sur le fichier fic, il est l'heure de partir je lance la sauvegarde :
cd..t...... ./ >f.st...... fic Number of files: 7 Number of files transferred: 1 Total file size: 7 bytes Total transferred file size: 7 bytes Literal data: 7 bytes Matched data: 0 bytes File list size: 132 File list generation time: 0.001 seconds File list transfer time: 0.000 seconds Total bytes sent: 193 Total bytes received: 35 sent 193 bytes received 35 bytes 456.00 bytes/sec total size is 7 speedup is 0.03
Seul le fichier fic à été transféré, maintenant le répertoire TARGET contient :
drwx------ 3 flipflip flipflip 4096 20 janv. 12:10 2012-01-20 drwx------ 3 flipflip flipflip 4096 21 janv. 12:15 2012-01-21
ls -l 2012-01-20 drwx------ 2 flipflip flipflip 4096 2 nov. 2010 dir1 -rwx------ 1 flipflip flipflip 0 20 janv. 12:10 fic -rwx------ 2 flipflip flipflip 0 2 nov. 2010 fic1 -rwx------ 2 flipflip flipflip 0 2 nov. 2010 fic2 ls -l 2012-01-21 drwx------ 2 flipflip flipflip 4096 2 nov. 2010 dir1 -rwx------ 1 flipflip flipflip 7 21 janv. 12:15 fic -rwx------ 2 flipflip flipflip 0 2 nov. 2010 fic1 -rwx------ 2 flipflip flipflip 0 2 nov. 2010 fic2
dir1, fic1 et fic2 sont des hard link qui occupe bien moins de place que le fichier d'origine. Il y a uniquement fic qui est mis à jour. La semaine continue et nous sommes le 26 normalement le répertoire TARGET devrait ressembler à ça :
drwx------ 3 flipflip flipflip 4096 27 janv. 12:10 2012-01-20 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-21 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-22 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-23 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-24 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-25
J'ai programmé une rétention de 5 jours, je lance la sauvegarde et magie :
drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-21 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-22 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-23 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-24 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-25 drwx------ 3 flipflip flipflip 4096 27 janv. 12:15 2012-01-26
La journée du 20 a disparue.
Je vous laisse bricoler les options de rsync.