vendredi 26 avril 2013

Sauvegarde incrémentale avec rsync

rsync est un programme Unix utilisé pour maintenir une copie d'une arborescence synchrone avec une autre en ne recopiant que les différences. Grâce à lui on peut donc réduire le nombre de fichier à recopier dans le cas d'arborescence qui change peu (c'est souvent utilisé dans le cadre de mirroir de site par exemple).

Pour ma part, je l'utilise souvent avec l'option -av :
rsync -av /mon/premier/repertoire /mon/repertoire/de/sauvegarde
On peut également rajouter l'option --delete afin que rsync procède également à la suppression des fichiers qui ont été supprimé d'un côté.

Seulement voilà, quand on veut faire une sauvegarde incrémentale pour conserver un historique de l'état d'une arborescence (ou les différentes versions d'un fichier), on se rend vite compte que c'est pas vraiment l'idéal. C'est là où on peut faire appel à la commande cp avec l'option -al (a = archive = préservation des liens symboliques + préservation des droits + copie récursive et l = pas de recopie mais utilisation d'un lien hard).

En faisant ainsi, on va recréer notre arborescence mais sans pour autant recopier les données (les fichiers seront identiques puisque pointant sur les mêmes inoeuds). Pour mieux comprendre, faisons quelques tests ...

Quelques tests sur les inoeuds ...

Créons un fichier quelconque :
$ cat > monfichier
Ceci est un fichier.
Recopions ce dernier avec la commande cp -al :
$ cp -al monfichier macopiedefichier
Regardons maintenant la valeur de l'inoeud :
$ ls -l1i monfichier macopiedefichier
457175 -rw-r--r-- 2 yannig yannig 21 Apr 26 15:52 macopiedefichier
457175 -rw-r--r-- 2 yannig yannig 21 Apr 26 15:52 monfichier
On se rend compte que ces deux fichiers sont en tout point identique. Maintenant, nous allons utiliser rsync pour faire cette recopie :
$ rsync -av monfichier uneautrecopie
Regardons à nouveau les inoeuds de nos fichiers :
$ ls -l1i monfichier macopiedefichier uneautrecopie
457175 -rw-r--r-- 2 yannig yannig 21 Apr 26 15:52 macopiedefichier
457175 -rw-r--r-- 2 yannig yannig 21 Apr 26 15:52 monfichier
457176 -rw-r--r-- 1 yannig yannig 21 Apr 26 15:52 uneautrecopie
Le nouveau fichier a bien un inoeud différent. Essayons maintenant de voir dans le cas d'un fichier déjà existant :
$ touch unautrefichier
Son numéro d'inoeud :
$ ls -i unautrefichier
457177 unautrefichier
Lançons maintenant notre synchronisation :
$ rsync -av macopiedefichier unautrefichier
Et jetons un coup d'oeil sur le résultat :
$ ls -l1i monfichier macopiedefichier uneautrecopie unautrefichier
457175 -rw-r--r-- 2 root root 21 Apr 26 15:52 macopiedefichier
457175 -rw-r--r-- 2 root root 21 Apr 26 15:52 monfichier
457178 -rw-r--r-- 1 root root 21 Apr 26 15:52 unautrefichier
457176 -rw-r--r-- 1 root root 21 Apr 26 15:52 uneautrecopie
On se rend bien compte que notre fichier de destination a bien été supprimé avant d'être recréé (457177 != 457178). Ce comportement est normal puisque c'est rsync qui fonctionne de cette manière.

Au final, ceci va donc me permettre de vous proposer un petit mécanisme de sauvegarde incrémentale.

A noter que si vous avez besoin de plus de détails pour comprendre les amis les inoeuds, je vous invite à vous tourner vers Wikipedia ou vers un bon bouquin sur Unix.

Passons maintenant à notre sauvegarde ...

Imaginons une arborescence /var/svn. Vous voulez sauvegarder tout ceci sur un serveur externe via rsync. Pour se faire, lançons tout d'abord une première sauvegarde depuis le serveur SVN :
rsync -av /var/svn/. backup:/var/backup/svn/.
Attention : Notre recopie à distance se fait à l'aide du protocole ssh. Il faudra donc avoir échangé les clés SSH entre le serveur SVN et celui de backup. Le répertoire /var/backup/svn devra également déjà exister sur la machine de backup.

Passons maintenant sur la machine de backup. Avant de lancer le rsync, nous allons d'abord recopier notre arborescence dans un nouveau répertoire en date du jour :
$ cp -al /var/backup/svn /var/backup/svn-date-du-jour
Ceci fait, nous pouvons maintenant lancer la commande de rsync :
$ rsync serveur-svn:/var/svn/. /var/backup/svn-date-du-jour/.
Reste maintenant plus qu'à faire un petit script de cette merveille combiné avec une crontab pour lancer ça automatiquement et vous voilà en face d'un superbe outil de sauvegarde !

A noter qu'il est également possible de se passer de la commande cp -al à l'aide de l'option --link-dest. En effet, cette dernière permet de faire un lien symbolique dans l'ancien répertoire dans le cas où les attributs externes du fichier n'aurait pas changé (permissions et date de modification). Dans ce cas, la commande à passer serait la suivante :
$ rsync --link-dest /var/backup/svn/. serveur-svn:/var/svn/. /var/backup/svn-date-du-jour/.