Sauvegardes par « snapshots » – La puissance de rsync et des liens durs

Sauvegardes

Je stocke une quantité inimaginable de scripts, de bouts de codes, de documents, de photos et de projets en tout genre sur mon serveur de fichiers. Quelques Go qui représentent des années de ma vie « numérique ». Le temps passe, le volume des données augmente et il devient urgent de trouver un moyen de sauvegarde plus rapide, plus efficace et surtout moins fastidieux que la gravure sur DVD. – Vous remarquerez au passage la photo prise en exclusivité pour l’illustration de cet article et sa superbe mise en scène réalisée sur le plan de travail de ma cuisine –
La sauvegarde sur DAT ou DLT étant bien trop onéreuse et surtout trop lente, j’ai opté pour le montage d’un serveur de sauvegardes « maison ».

Mise en place :

* Côté matériel, un petit Céléron 900Mhz de récupération fera très bien l’affaire. Je le gonfle un peu en montant la ram à 384Mo et attribue le gros du budget au stockage en lui offrant deux beaux disques dur IDE de 320Go – Ca ! C’est classe ! –

* Côté logiciel, une distribution Debian et un petit script qui combine rsync pour optimiser les transferts réseaux et des liens durs pour garder un historique en limitant l’espace disque utilisé.

Pour simplifier les choses, nous allons appeler le serveur de fichiers « serv_file » et le serveur de sauvegardes « serv_nas« .

Les présentations étant faites, commençons par générer un bi-clés pour ssh sur serv_nas et faire une copie de la clef publique sur serv_file, pour que mon premier puisse parler à mon second, via ssh et sans avoir à fournir de mot de passe. C’est quand même bien plus pratique pour automatiser le bazar !

Concrètement, comment fait-on ?
Sur serv_nas :

srv_nas:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
2d:40:c4:09:67:06:...b:bf:06 root@srv_nas
srv_nas:~# ssh-copy-id root@srv_file
root@srv_file's password :

Tout c’est bien passé ? L’ouverture d’une session ssh de serv_nas vers serv_file devrait se faire sans mot de passe. Essayons…

srv_nas:~# ssh srv_file
Last login: Mon Mar 17 18:10:25 2008 from 192.168.7.102
Linux srv_file 2.6.18-6-686 #1 SMP Sun Feb 10 22:11:31 UTC 2008 i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
srv_file:~#
srv_file:~# exit

srv_nas~#

Si ce n’est pas déjà fait, il faut maintenant installer rsync sur les deux machines :

srv_nas:~# aptitude install rsync
srv_nas:~# ssh srv_file aptitude install rsync

Le script – Initialisation

Allez ! Fini la rigolade, passons au script…
La première chose à faire est de déclarer quelques variables…C’est quand bien plus propre et ça facilite la modification du script par la suite.

#!/bin/bash
#------Début du fichier /usr/local/scripts/snapshot.sh
 
SERVEUR="srv_file"
DST="/srv/sauvegardes"
LOG="/var/log/snapshot-$SERVEUR.log"
DATE=`date +%y%m%d-%H%M`

Le script – rsync :

L’étape suivante, va consister à boucler sur les répertoires à sauvegarder (etc, home, root, data, srv et var dans l’exemple) pour en faire un miroir dans un dossier local nommé « current » (/srv/sauvegardes/current). Ce dernier contiendra toujours la dernière image des fichiers sauvegardés.
La commande rsync avec les options suivantes est la plus à même de réaliser ce travail :

# SYNCHRONISATION
 
echo "Début de la sauvegarde le `date +%D` à `date +%H:%M` " >> $LOG
for REP in etc home root data srv var ;  do
    echo "    *    Sauvegarde de  $REP" >> $LOG
    rsync -ra --delete $SERVEUR:/$REP $DST/current 2>> $LOG
done;

Le grand intérêt dans l’utilisation de la commande rsync réside dans le fait que, contrairement à scp, elle ne va copier que les fichiers différents ou inexistants dans le répertoire destination et donc procurer un immense gain de bande passante et de temps.

Le script – Les liens durs :

La dernière étape va créer une image datée du répertoire « current », avant que la prochaine synchronisation ne vienne en altérer le contenu, en optimisant l’espace disque utilisé.

Pour cette opération, la puissante des liens durs va nous être très utile.

Les liens durs associent deux ou plusieurs fichiers à un même espace sur le disque. Les deux fichiers restent indépendants, tout en partageant le même espace disque et donc le même inode . Toute modification de l’un, modifie l’autre, mais la suppression de l’un, casse le lien et ne supprime pas physiquement l’autre.

Dans notre cas, nous allons créer un lien dur de notre dossier « current » et de son contenu vers un dossier portant la valeur de notre variable $DATE (la date et l’heure du début de la sauvegarde).
Il suffit pour cela d’utiliser la commande « cp » avec les options :

# SNAPSHOT
 
cp -al $DST/current $DST/$DATE 2>> $LOG
 
echo "Fin de la sauvegarde le `date +%D` à `date +%H:%M` " >> $LOG
echo "========================================" >> $LOG
 
#------Fin du fichier /usr/local/scripts/snapshot.sh

En résumé :

Juste après l’exécution du script, le répertoire current et le répertoire « daté » sont identiques. Comme le second est créé par « liens durs », aucun espace disque supplémentaire n’est consommé.

Lors de la sauvegarde suivante, la commande rsync va modifier le répertoire « current » :

En résumé, cette mécanique va permettre de garder un historique des fichiers du serveur, jour après jour, en ne consommant que l’espace utilisé par les ajouts ou modifications de fichiers.

Capture

La notion de lien est complètement transparente pour l’utilisateur et sous chaque répertoire, nous retrouvons l’ensemble des fichiers, tels qu’ils étaient sur le serveur à la date correspondante; d’où le nom de « snapshot » donné à cette technique (et à mon script !)

Pour finir, voici le petit script en un seul morceau :

#!/bin/bash
#------Début du fichier /usr/local/scripts/snapshot.sh
 
# PARAMETRE
SERVEUR="srv_file"
DST="/srv/sauvegardes"
LOG="/var/log/snapshot-$SERVEUR.log"
DATE=`date +%y%m%d-%H%M`
 
# SYNCHRONISATION
echo "Début de la sauvegarde le `date +%D` à `date +%H:%M` " >> $LOG
for REP in etc home root data srv var ;  do
    echo "    *    Sauvegarde de  $REP" >> $LOG
    rsync -ra --delete $SERVEUR:/$REP $DST/current 2>> $LOG
done;
 
# SNAPSHOT
cp -al $DST/current $DST/$DATE 2>> $LOG
echo "Fin de la sauvegarde le `date +%D` à `date +%H:%M` " >> $LOG
echo "========================================" >> $LOG
 
#------Fin du fichier /usr/local/scripts/snapshot.sh

Laissez votre message après le bip...Biiiiip

Commentaires

Bonjour,
j’aimerais savoir comment on peut faire pour supprimer dans une commande RSYNC les dossiers et les fichiers qui ne sont plus présent sur le répertoire à sauvegarder.

Ma ligne de commande ressemble à celle-ci :

rsync -av –delete –ignore-errors –force -e ssh /mnt/REP/Divers/* SERVEUR/REP/Divers

Seulement, ma commande delete ne fonctionne pas et n’est sensée fonctioner que pour les fichiers alors que j’aimerais également l’appliquer pour les dossiers.

Merci de m’aider.

Bonjour,

Essaye sans l’*’… :
rsync -av –delete (…) /mnt/REP/Divers SERVEUR:/REP/

Quand tu utilises la wildcards « * », tu synchronise chaque fichiers et dossiers du répertoire Divers, et non le répertoire Divers complet. Si tu supprimes un sous-répertoire de « Divers » sur le serveur source, il n’est tout simplement plus synchronisé et n’est pas effacé dans le répertoire destination.

Si tu synchronises à un niveau supérieur (REP/Divers directement), c’est bien l’intégralité du répertoire qui est synchronisé.

Comme précisé dans le titre de l’article…C’est puissant 😉

Bonjour.

Merci Jopa pour ton aide précieuse, notre sauvegarde fonctionne correctement maintenant.
J’ajouterais juste une précision, il faut bien supprimer la wildcards “*” mais pas le « / » et en effet… c’est plus simple.

Bonjour Jopa,

Petite question en passant, je compte mettre une petite chose comme celle la en place, mais (oui il y a un mais), j’aurais quelques questions.

1 – Peut on faire une sauvegarde complète d’un serveur comme ca (et quand je dis complète c’est complète ?

2 – N’y aurait-il pas de soucis avec des bdd genre mysql ou des fichiers en cours d’utilisation par exemple ?

En tous cas le script me fait de l’oeil.

Voila c’est tout

Ha non une dernière chose, je présume que de déclencher le script suffit à le faire se connecter automatiquement en ssh au serveur sur lequel récupérer les fichiers ?

Encore merci Jopa

Rhoo et j’avais oublié une question (je sais je suis impardonnable),

Mais que faire si en ssh on n’empêche l’utilisation du compte root ?

Bonjour Tarlak,

1 – Oui, on peut faire une sauvegarde complète d’un serveur… Par contre, si tu penses à la création d’une image qui te permettrait de remonter le serveur facilement, regarde du côté de « Mondo »… C’est plus adapté, par contre, plus volumineux en stockage, car une image complète est crée à chaque sauvegarde,
2 – Effectivement, pour les bases de données, il convient d’arrêter le sgbd (mysql ou postgresql) avant la sauvegarde. De mon côté, je préfère un dump sql, qui peut se réaliser à chaud (mysqldump ou pgdump) et est plus indépendant des versions.
3 – Le script peut-être adapté pour utiliser un utilisateur autre que root. Se pose quand même le problème d’accès aux fichiers à sauvegarder. Après, selon la configuration, on peut également adapter le sens : Le serveur de sauvegardes va « chercher » les fichiers sur les différents serveurs, ou les différents serveurs poussent les fichiers vers le serveur de sauvegarde.

Merci pour le script, je l’ai un peu adapté car je souhaite avoir des snapshots qu’en local sur 2 de mes serveurs pour l’instant mais je vais sûrement à nouveau l’utiliser via le réseau aussi. (j’hésite d’ailleurs à tout simplement le faire sur un montage NFS)

Je trouve ce script trés intéressant mais après avoir fait quelques tests, j\’aurais besoin d\’une précision : les liens en durs permettent t\’il vraiment une historique de chaque fichiers? J\’ai fait des essais et si je modifie le fichier d\’origine le fichier lien dur est modifié également. si je recopie un nouveau fichier sur le fichier source, le lien dur est modifié également, ce qui sembkle normal. Mais comment faire pour avoir une historique des fichiers

autant pour moi. ce script est vraiment extra. sauvegardes impécables. Merci encore à Jopa de nous l’avoir donné

Laisser un commentaire

(requis)

(requis)