« Les sauvegardes » : différence entre les versions

De Lea Linux
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
(balises code)
 
Ligne 38 : Ligne 38 :
===== Présentation des options =====
===== Présentation des options =====
Pour créer une archive, il suffit d'utiliser la commande:
Pour créer une archive, il suffit d'utiliser la commande:
<code>tar c nom_archive [fichier repertoire1] [fichier ou repertoire2]...</code>
<span class="code">tar c nom_archive [fichier repertoire1] [fichier ou repertoire2]...</span>
Différentes options peuvent s'avérer utiles :
Différentes options peuvent s'avérer utiles :
* -v : mode verbeux, liste les fichiers qui sont en cours d'archivage
* -v : mode verbeux, liste les fichiers qui sont en cours d'archivage
Ligne 47 : Ligne 47 :
* -X fichier : ''fichier'' est un fichier où chaque ligne correspond à un fichier ou répertoire à exclure parmis les répertoires à sauvegarder
* -X fichier : ''fichier'' est un fichier où chaque ligne correspond à un fichier ou répertoire à exclure parmis les répertoires à sauvegarder
* --exclude=fichier : ''fichier'' sera exclu de la sauvegarde
* --exclude=fichier : ''fichier'' sera exclu de la sauvegarde
* -N date : permet de ne sauvegarder que les fichiers postérieurs à la date définie. La date doit être fournie sous la forme ''AAAA-MM-JJ HH:MM:SS". On obtient se format grâce à la commande <code>date "+%Y:%m:%d %H:%M:%S"</code>
* -N date : permet de ne sauvegarder que les fichiers postérieurs à la date définie. La date doit être fournie sous la forme ''AAAA-MM-JJ HH:MM:SS". On obtient se format grâce à la commande <span class="code">date "+%Y:%m:%d %H:%M:%S"</span>
* --totals : affiche le nombre d'octets écrits lors de la sauvegarde
* --totals : affiche le nombre d'octets écrits lors de la sauvegarde
* -g fichier : permet d'effectuer des sauvegardes incrémentales, en se basant sur un fichier de status. Ce fichier est soit utilisé (sauvegarde incrémentale), soit créé (sauvegarde full). Attention, cette option n'est valable que pour les versions GNU!
* -g fichier : permet d'effectuer des sauvegardes incrémentales, en se basant sur un fichier de status. Ce fichier est soit utilisé (sauvegarde incrémentale), soit créé (sauvegarde full). Attention, cette option n'est valable que pour les versions GNU!
Ligne 55 : Ligne 55 :
===== Exemple de sauvegarde de données =====
===== Exemple de sauvegarde de données =====
Voici un petit script permettant de mettre en place une sauvegarde totale et/ou différentielle de données :
Voici un petit script permettant de mettre en place une sauvegarde totale et/ou différentielle de données :
<code>#!/bin/bash
<div class="code">
#!/bin/bash


# Options
# Options
# -d : sauvegarde differentielle
# -d : sauvegarde differentielle
# -h : affiche les options possibles
# -h : affiche les options possibles


# Si on demande l'aide, on l'affiche, et on sort
# Si on demande l'aide, on l'affiche, et on sort
if [ "$1" = "-h" ] ; then
if [ "$1" = "-h" ] ; then
   echo "Usage : $0 : sauvegarde totale"
   echo "Usage : $0 : sauvegarde totale"
   echo "Usage : $0 -d : sauvegarde différentielle"
   echo "Usage : $0 -d : sauvegarde différentielle"
   echo "Usage : $0 -h : cette aide"
   echo "Usage : $0 -h : cette aide"
fi
fi


# Initialisation des variables
# Initialisation des variables
DATE=$(date "+%Y-%m-%d %H:%M:%S")
DATE=$(date "+%Y-%m-%d %H:%M:%S")
TYPE="FULL"
TYPE="FULL"
REP=/backup
REP=/backup
FICHIER_EXCLUDE=/etc/save.exclude
FICHIER_EXCLUDE=/etc/save.exclude
FICHIER_INCLUDE=/etc/save.include
FICHIER_INCLUDE=/etc/save.include
FICHIER_STATUS=/etc/save.state
FICHIER_STATUS=/etc/save.state
COMPRESSION=9
COMPRESSION=9


# Si le script est appelé avec l'option "-d", alors on fait une sauvegarde différentielle
# Si le script est appelé avec l'option "-d", alors on fait une sauvegarde   différentielle
if [ "$1" = "-d" ] ; then
if [ "$1" = "-d" ] ; then
     TYPE="INCR"
     TYPE="INCR"
     tar cP --atime-preserve -g $FICHIER_STATUS --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > ${REP}/save-INCR-${DATE}.tgz
     tar cP --atime-preserve -g $FICHIER_STATUS --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > ${REP}/save-INCR-${DATE}.tgz
# Sinon, on fait une sauvegarde totale
# Sinon, on fait une sauvegarde totale
else
else
     rm -f $FICHIER_STATUS
     rm -f $FICHIER_STATUS
     tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > ${REP}/save-FULL-${DATE}.tgz
     tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > ${REP}/save-FULL-${DATE}.tgz
fi
fi
</code>
</div>


===== Exemple de sauvegarde système =====
===== Exemple de sauvegarde système =====
Ligne 92 : Ligne 93 :


Le fichier save.conf doit être de la forme :
Le fichier save.conf doit être de la forme :
<code>EXCLUDE="/repertoire1 /repertoire2"
<div class="code">EXCLUDE="/repertoire1 /repertoire2"
# Le reste est optionnel
# Le reste est optionnel


#COMPRESSION=1
#COMPRESSION=1
#SERVEUR="10.0.0.2:/path
#SERVEUR="10.0.0.2:/path
#MONTAGE="/mnt/nfs"
#MONTAGE="/mnt/nfs"
#INCLUDE="/toto"
#INCLUDE="/toto"
</code>
</div>


Et le script :
Et le script :


<code>#!/bin/sh
<div>
#!/bin/sh


# Options
# Options
# -d : sauvegarde differentielle
# -d : sauvegarde differentielle
# -h : affiche les options possibles
# -h : affiche les options possibles


# Si on demande l'aide, on l'affiche, et on sort
# Si on demande l'aide, on l'affiche, et on sort
if [ $1 = "-h" ] ; then
if [ $1 = "-h" ] ; then
   echo "Usage : $0 : sauvegarde totale"
   echo "Usage : $0 : sauvegarde totale"
   echo "Usage : $0 -d : sauvegarde différentielle"
   echo "Usage : $0 -d : sauvegarde différentielle"
   echo "Usage : $0 -h : cette aide"
   echo "Usage : $0 -h : cette aide"
fi
fi


PID=$$
PID=$$


# On donne une priorité faible au processus pour ne pas dégrader les performances des autres applications
# On donne une priorité faible au processus pour ne pas dégrader les performances des autres applications
renice +19 $PID
renice +19 $PID
. /etc/save.conf
. /etc/save.conf


MONTAGE=${MONTAGE:="/tmp/save.$PID"}
MONTAGE=${MONTAGE:="/tmp/save.$PID"}
SERVEUR=${SERVEUR:="10.0.0.1:/backup"}
SERVEUR=${SERVEUR:="10.0.0.1:/backup"}


COMPRESSION=${COMPRESSION:=9}
COMPRESSION=${COMPRESSION:=9}
NOM=$(hostname)
NOM=$(hostname)
CONFIGURATION=${MONTAGE}/${NOM}.conf
CONFIGURATION=${MONTAGE}/${NOM}.conf
DATE="$(date "+%Y-%m-%d %H:%M:%S")"
DATE="$(date "+%Y-%m-%d %H:%M:%S")"
FICHIER_EXCLUDE=/tmp/save.$PID.exlude
FICHIER_EXCLUDE=/tmp/save.$PID.exlude
FICHIER_INCLUDE=/tmp/save.$PID.include
FICHIER_INCLUDE=/tmp/save.$PID.include
FICHIER_STATUS=/etc/save.state
FICHIER_STATUS=/etc/save.state
LVMVERSION=1
LVMVERSION=1


affiche_action() {
affiche_action() {
echo -e "$1 ........... \c"
echo -e "$1 ........... \c"
}
}


affiche_resultat() {
affiche_resultat() {
if [ $1 = 0 ] ; then
if [ $1 = 0 ] ; then
echo -e '[\c'
echo -e '[\c'
Ligne 154 : Ligne 156 :
return 1
return 1
fi
fi
}
}


quit() {
quit() {
affiche_action "Nettoyage en cours"
affiche_action "Nettoyage en cours"
rm -f $FICHIER_EXCLUDE
rm -f $FICHIER_EXCLUDE
Ligne 164 : Ligne 166 :
affiche_resultat $?
affiche_resultat $?
exit $1
exit $1
}
}


# Montage du partage nfs
# Montage du partage nfs
affiche_action "Montage du partage NFS vers $SERVER"
affiche_action "Montage du partage NFS vers $SERVER"
mkdir $MONTAGE
mkdir $MONTAGE
mount -t nfs $SERVER $MONTAGE
mount -t nfs $SERVER $MONTAGE
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


# Sauvegarde des donnees de partitionnement
# Sauvegarde des donnees de partitionnement
affiche_action "Sauvegarde du partitionnement"
affiche_action "Sauvegarde du partitionnement"
echo "[disks]" > $CONFIGURATION
echo "[disks]" > $CONFIGURATION
/sbin/fdisk -l | tr '*' ' ' | awk '/^\/dev/ {print $1,$2,$3,$5}' >> $CONFIGURATION
/sbin/fdisk -l | tr '*' ' ' | awk '/^\/dev/ {print $1,$2,$3,$5}' >>   $CONFIGURATION
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


echo "[bootdisk]" >> $CONFIGURATION
echo "[bootdisk]" >> $CONFIGURATION
fdisk -l | awk '/^\/dev\/.*\*/ {print $1}' >> $CONFIGURATION
fdisk -l | awk '/^\/dev\/.*\*/ {print $1}' >> $CONFIGURATION


# Sauvegarde du lvm : PV, VG, LV et version du LVM
# Sauvegarde du lvm : PV, VG, LV et version du LVM
affiche_action "Sauvegarde des groupes de volumes du LVM"
affiche_action "Sauvegarde des groupes de volumes du LVM"


echo "[LVM-VG]" >> $CONFIGURATION
echo "[LVM-VG]" >> $CONFIGURATION
liste=$(pvscan | grep -o 'PV.*/dev/.*VG.*' | tr -d '"' | sed 's,^.*PV \(/dev/[^ ]*\).* VG \([^ ]*\).*,\1 \2,')
liste=$(pvscan | grep -o 'PV.*/dev/.*VG.*' | tr -d '"' | sed 's,^.*PV   \(/dev/[^ ]*\).* VG \([^ ]*\).*,\1 \2,')
liste2=$(echo $liste | grep -o '/dev/[^ ]*')
liste2=$(echo $liste | grep -o '/dev/[^ ]*')
for element in $liste2 ; do
for element in $liste2 ; do
         LVM=1
         LVM=1
         $REP/bin/lvm.static pvscan 2>/dev/null | grep $element 2>/dev/null | grep -q lvm2
         $REP/bin/lvm.static pvscan 2>/dev/null | grep $element 2>/dev/null | grep -q lvm2
         [ $? = 0 ] && LVM=2
         [ $? = 0 ] && LVM=2
         echo $(echo $liste | grep -o "$element [^ ]*") $LVM >> $CONFIGURATION
         echo $(echo $liste | grep -o "$element [^ ]*") $LVM >> $CONFIGURATION
done
done
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


affiche_action "Sauvegarde des volumes logiques du LVM"
affiche_action "Sauvegarde des volumes logiques du LVM"
echo "[LVM-LV]" >> $CONFIGURATION
echo "[LVM-LV]" >> $CONFIGURATION
for volume in $(lvscan | grep -o '"/dev[^"]*"' | tr -d '"') ; do
for volume in $(lvscan | grep -o '"/dev[^"]*"' | tr -d '"') ; do
extend=$(lvdisplay $volume | awk '/Allocated LE/ {print $3}')
extend=$(lvdisplay $volume | awk '/Allocated LE/ {print $3}')
echo "$volume $extend" >> $CONFIGURATION
echo "$volume $extend" >> $CONFIGURATION
done
done
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


# Sauvegarde des labels
# Sauvegarde des labels
affiche_action "Sauvegarde des labels des partitions"
affiche_action "Sauvegarde des labels des partitions"
echo "[labels]" >> $CONFIGURATION
echo "[labels]" >> $CONFIGURATION
for partition in $(/sbin/fdisk -l | grep -o '^/dev/[^ ]*') ; do
for partition in $(/sbin/fdisk -l | grep -o '^/dev/[^ ]*') ; do
label=$(/sbin/e2label $partition 2>/dev/null)
label=$(/sbin/e2label $partition 2>/dev/null)
echo "$partition=$label" >> $CONFIGURATION
echo "$partition=$label" >> $CONFIGURATION
done
done
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


# Sauvegarde des points de montage
# Sauvegarde des points de montage
affiche_action "Sauvegarde des points de montage"
affiche_action "Sauvegarde des points de montage"
echo "[montage]" >> $CONFIGURATION
echo "[montage]" >> $CONFIGURATION
mount | awk '/ext[23]/ {print $1,$3}' >> $CONFIGURATION
mount | awk '/ext[23]/ {print $1,$3}' >> $CONFIGURATION
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


# Sauvegarde de la hierarchie exclue
# Sauvegarde de la hierarchie exclue
affiche_action "Creation de la liste des repertoires exclus a recontruire"
affiche_action "Creation de la liste des repertoires exclus a recontruire"
echo "[hierarchie]" >> $CONFIGURATION
echo "[hierarchie]" >> $CONFIGURATION
rm -f $FICHIER_EXCLUDE
rm -f $FICHIER_EXCLUDE


# On exclu les partages NFS et les montages loop
# On exclu les partages NFS et les montages loop
mount | awk '/type nfs/ { print $3}' >> $FICHIER_EXCLUDE
mount | awk '/type nfs/ { print $3}' >> $FICHIER_EXCLUDE
mount | awk '/loop=/ { print $3}' >> $FICHIER_EXCLUDE
mount | awk '/loop=/ { print $3}' >> $FICHIER_EXCLUDE


# Rajout des répertoires à exclure par défaut
# Rajout des répertoires à exclure par défaut
[ -d /media ] && EXCLUDE="/media $EXCLUDE"
[ -d /media ] && EXCLUDE="/media $EXCLUDE"
EXCLUDE="/mnt /sys /dev /tmp /proc /var/run /var/log /var/lock /var/spool /var/tmp /var/cache $EXCLUDE"
EXCLUDE="/mnt /sys /dev /tmp /proc /var/run /var/log /var/lock /var/spool /var/tmp /var/cache $EXCLUDE"
for rep in $EXCLUDE ; do
for rep in $EXCLUDE ; do
case $rep in
case $rep in
/mnt)
/mnt)
Ligne 240 : Ligne 242 :
/media)
/media)
echo "/media" >> $CONFIGURATION
echo "/media" >> $CONFIGURATION
[ -d /media ] && for rep in $(ls -F /media | tr -d '/') ; do
[ -d /media ] && for rep in $(ls -F /media | tr -d '/') ; do
[ -d /media/$rep ] && echo "/media/$rep" >> $CONFIGURATION
[ -d /media/$rep ] && echo "/media/$rep" >> $CONFIGURATION
done
done
Ligne 266 : Ligne 268 :
esac
esac
echo $rep >> $FICHIER_EXCLUDE
echo $rep >> $FICHIER_EXCLUDE
done
done
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1
echo '*/lost+found' >> $FICHIER_EXCLUDE
echo '*/lost+found' >> $FICHIER_EXCLUDE


# Sauvegarde de grub
# Sauvegarde de grub
affiche_action "Sauvegarde de grub"
affiche_action "Sauvegarde de grub"
echo "[GRUB]" >> $CONFIGURATION
echo "[GRUB]" >> $CONFIGURATION
cat /boot/grub/menu.lst | grep '^[^#].*root (hd' | head -n 1 | grep -o 'root.*' >> $CONFIGURATION
cat /boot/grub/menu.lst | grep '^[^#].*root (hd' | head -n 1 | grep -o 'root.*' >> $CONFIGURATION
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1


# Si l'option -d est passee en parametre, on fait une sauvegarde differentielle
# Si l'option -d est passee en parametre, on fait une sauvegarde differentielle
INCLUDE=${INCLUDE:=/}
INCLUDE=${INCLUDE:=/}
rm -f $FICHIER_INCLUDE
rm -f $FICHIER_INCLUDE
for rep in $INCLUDE ; do
for rep in $INCLUDE ; do
echo $rep >> $FICHIER_INCLUDE
echo $rep >> $FICHIER_INCLUDE
done
done


if [ $# -ge 1 ] && [ $1 = "-d" ] ; then
if [ $# -ge 1 ] && [ $1 = "-d" ] ; then
affiche_action "Sauvegarde du systeme sur $SERVEUR/${NOM}-INCR-${DATE}"
affiche_action "Sauvegarde du systeme sur $SERVEUR/${NOM}-INCR-${DATE}"
tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > $MONTAGE/${NOM}-INCR-${DATE}.tar.gz
tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > $MONTAGE/${NOM}-INCR-${DATE}.tar.gz
affiche_resultat $? || quit 1
affiche_resultat $? || quit 1
else
else
affiche_action "Sauvegarde du systeme sur $SERVEUR/${NOM}-FULL-${DATE}"
affiche_action "Sauvegarde du systeme sur $SERVEUR/${NOM}-FULL-${DATE}"
         rm -f $FICHIER_STATUS
         rm -f $FICHIER_STATUS
Ligne 294 : Ligne 296 :
fi
fi


# Sauvegarde de MAKEDEV qui se trouve dans /dev
# Sauvegarde de MAKEDEV qui se trouve dans /dev
affiche_action "Sauvegarde de MAKEDEV"
affiche_action "Sauvegarde de MAKEDEV"
[ -f /dev/MAKEDEV ] && cp /dev/MAKEDEV $MONTAGE/
[ -f /dev/MAKEDEV ] && cp /dev/MAKEDEV $MONTAGE/
affiche_resultat 0
affiche_resultat 0


quit 0
quit 0
</code>
</div>


==== Restauration avec tar ====
==== Restauration avec tar ====
===== Présentation de la commande =====
===== Présentation de la commande =====
Pour restaurer un tar, il suffit d'utiliser la commande:
Pour restaurer un tar, il suffit d'utiliser la commande:
<code>tar x nom_archive</code>
<span class="code">tar x nom_archive</span>
Là encore, il existe diverses options:
Là encore, il existe diverses options:
* -v : mode verbeux : afficher les fichiers en cours d'extraction
* -v : mode verbeux : afficher les fichiers en cours d'extraction
Ligne 317 : Ligne 319 :


Voici un exemple de commande pour restaurer une archive :
Voici un exemple de commande pour restaurer une archive :
<code>tar zxvf --atime-preserve --preserve --same-owner --numeric-owner /backup/archive.tgz</code>
<span class="code">tar zxvf --atime-preserve --preserve --same-owner --numeric-owner /backup/archive.tgz</span>


=== la commande rsync ===
=== la commande rsync ===
Ligne 325 : Ligne 327 :
==== La commande rsync ====
==== La commande rsync ====
Pour l'utiliser il suffit d'utiliser:
Pour l'utiliser il suffit d'utiliser:
<code>rsync [options] source(s) destination</code>
<span class="code">rsync [options] source(s) destination</span>


Les options :
Les options :
Ligne 354 : Ligne 356 :
Dans la crontab de la machine à sauvegarder, vers 22h00, on lance le script suivant :
Dans la crontab de la machine à sauvegarder, vers 22h00, on lance le script suivant :


<code>#!/bin/sh
<div class="code">#!/bin/sh
# répertoires à sauvegarder
# répertoires à sauvegarder
DIRS="/home/jice /home/fred /etc /root /boot /var/lib/mysql /var/spool/mail"
DIRS="/home/jice /home/fred /etc /root /boot /var/lib/mysql /var/spool/mail"
# fichier contenant les fichiers à exclure de la sauvegarde
# fichier contenant les fichiers à exclure de la sauvegarde
# voir EXCLUDE PATTERNS dans rsync(1)
# voir EXCLUDE PATTERNS dans rsync(1)
EXCLUDEFILE="/home/jice/bin/excludes"
EXCLUDEFILE="/home/jice/bin/excludes"
OPTIONS="-avz -e ssh"
OPTIONS="-avz -e ssh"
OPTIONS="$OPTIONS --exclude-from $EXCLUDEFILE --bwlimit=50"
OPTIONS="$OPTIONS --exclude-from $EXCLUDEFILE --bwlimit=50"
OPTIONS="$OPTIONS $*"
OPTIONS="$OPTIONS $*"
rsync $OPTIONS $DIRS jice@mon.serveur.net:backup/current
rsync $OPTIONS $DIRS jice@mon.serveur.net:backup/current
# copie du fichier "flag" pour dire au serveur que le backup a été fait
# copie du fichier "flag" pour dire au serveur que le backup a été fait
scp /home/jice/bin/backup_done jice@mon.serveur.net:~
scp /home/jice/bin/backup_done jice@mon.serveur.net:~
</code>
</div>


Ce script fait un backup vers le répertoire <code>backup/current</code> du serveur (nommé <code>mon.serveur.net</code>) ; à la fin, il copie un fichier (vide) <code>backup_done</code> à la racine de mon compte sur le serveur, afin de dire au serveur que le backup a bien été fait.
Ce script fait un backup vers le répertoire <span class="code">backup/current</span> du serveur (nommé <span class="code">mon.serveur.net</span>) ; à la fin, il copie un fichier (vide) <span class="code">backup_done</span> à la racine de mon compte sur le serveur, afin de dire au serveur que le backup a bien été fait.


PS : voici un exemple de fichier <code>excludes</code>
PS : voici un exemple de fichier <span class="code">excludes</span>
<code># excludes pour le backup sur zowie
<div class="code">
jice/tmp*
# excludes pour le backup sur zowie
jice/multimedia/video/*
jice/tmp*
jice/compil/*
jice/multimedia/video/*
fred/compil/*
jice/compil/*
*/.local/share/Trash/*
fred/compil/*
*/.kde/share/config/session/konqueror*
*/.local/share/Trash/*
*/temp/*
*/.kde/share/config/session/konqueror*
*/tmp/*
*/temp/*
*/cache/*
*/tmp/*
*/Cache/*
*/cache/*
*/.thumbnails/*
*/Cache/*
*/.xvpics/*
*/.thumbnails/*
*/.kde/tmp-*
*/.xvpics/*
*/.mcop/*
*/.kde/tmp-*
*/.ncftp/trace*
*/.mcop/*
*/.nx/*
*/.ncftp/trace*
*.o
*/.nx/*
*.so
*.o
*.mp3
*.so
*.avi
*.mp3
*.rar
*.avi
*.ace</code>
*.rar
*.ace</div>


Notez que ce fichier peut contenir ou bien le nom complet d'un fichier, ou bien un "morceau" de nom de fichier avec des étoiles comme caractère joker. Pour plus d'information, tapez dans une console : <code>man rsync</code> et cherchez EXCLUDE PATTERNS.
Notez que ce fichier peut contenir ou bien le nom complet d'un fichier, ou bien un "morceau" de nom de fichier avec des étoiles comme caractère joker. Pour plus d'information, tapez dans une console : <span class="code">man rsync</span> et cherchez EXCLUDE PATTERNS.


=====Côté serveur de sauvegarde=====
=====Côté serveur de sauvegarde=====
Côté serveur, j'ai ce script qui fait une rotation des backups (en cron tous les  midi) :
Côté serveur, j'ai ce script qui fait une rotation des backups (en cron tous les  midi) :
<code>#!/bin/sh
<div class="code">
#!/bin/sh


if [ -f ~/backup_done ]; then
if [ -f ~/backup_done ]; then
         KEEP=8
         KEEP=8
         DIR=~/backup
         DIR=~/backup
Ligne 427 : Ligne 431 :


         # on fait le rsync ensuite
         # on fait le rsync ensuite
fi</code>
fi</div>


Si le backup a été fait (présence du fichier <code>backup_done</code>, il effectue une rotation des backups.<br>
Si le backup a été fait (présence du fichier <span class="code">backup_done</span>, il effectue une rotation des backups.<br>
En utilisant le <code>cp</code> avec les hard links, on ne copie pas réellement les fichiers, mais on crée un deuxième fichier qui pointe vers le contenu du premier (donc on peut avoir autant de hardlink qu'on veut sur le même fichier, la place disque utilisée n'est toujours que de la taille d'un seul fichier).<br>
En utilisant le <span class="code">cp</span> avec les hard links, on ne copie pas réellement les fichiers, mais on crée un deuxième fichier qui pointe vers le contenu du premier (donc on peut avoir autant de hardlink qu'on veut sur le même fichier, la place disque utilisée n'est toujours que de la taille d'un seul fichier).<br>
Rsync lorsqu'il enverra, lors de la prochaine sauvegarde, un fichier modifié, utilisera un nom différent temporaire, avant de le renommer vers son nom normal. Ainsi, il ne va pas écraser le contenu du fichier hardlinké, car à la fin de la copie du fichier, Rsync supprime le fichier, puis renomme le fichier temporaire vers son nom normal.<br>
Rsync lorsqu'il enverra, lors de la prochaine sauvegarde, un fichier modifié, utilisera un nom différent temporaire, avant de le renommer vers son nom normal. Ainsi, il ne va pas écraser le contenu du fichier hardlinké, car à la fin de la copie du fichier, Rsync supprime le fichier, puis renomme le fichier temporaire vers son nom normal.<br>


A ce moment là, on a sur le serveur 2 versions du même fichier : la version courante qui vient d'être sauvegardée dans <code>~/backup/current/repertoire/fichier</code> et la version précédente qui a été copiée par le script ci-dessus dans <code>~/backup/<la date du dernier backup>/repertoire/fichier</code>.
A ce moment là, on a sur le serveur 2 versions du même fichier : la version courante qui vient d'être sauvegardée dans <span class="code">~/backup/current/repertoire/fichier</span> et la version précédente qui a été copiée par le script ci-dessus dans <span class="code">~/backup/<la date du dernier backup>/repertoire/fichier</span>.


'''Plus d'explications''' :
'''Plus d'explications''' :
* on a deux fichiers <code>current/toto</code> et <code>hier/toto</code> qui pointent vers le même contenu. Ces 2 fichiers (ou plus) on été obtenus suite au script de rotation, par la copie avec hardlinks. On a donc :
* on a deux fichiers <span class="code">current/toto</span> et <span class="code">hier/toto</span> qui pointent vers le même contenu. Ces 2 fichiers (ou plus) on été obtenus suite au script de rotation, par la copie avec hardlinks. On a donc :
<code>current/toto --> contenu <-- hier/toto
<span class="code">current/toto --> contenu <-- hier/toto
                               \
                               \
                                 '--------- avant-hier/toto
                                 '--------- avant-hier/toto
</code>
</span>
* si le fichier a été modifié, rsync va envoyer le nouveau fichier sous un nom temporaire <code>toto.tmp</code> (par exemple). On a donc :
* si le fichier a été modifié, rsync va envoyer le nouveau fichier sous un nom temporaire <span class="code">toto.tmp</span> (par exemple). On a donc :
<code>current/toto --> contenu <-- hier/toto
<span class="code">current/toto --> contenu <-- hier/toto
                               \
                               \
                                 '--------- avant-hier/toto
                                 '--------- avant-hier/toto


current/toto.tmp --> nouveau contenu</code>
current/toto.tmp --> nouveau contenu</span>
* ensuite, rsync supprime <code>current/toto</code> On obtient, par la magie des  hardlinks :
* ensuite, rsync supprime <span class="code">current/toto</span> On obtient, par la magie des  hardlinks :
<code>                contenu <-- hier/toto
<span class="code">                contenu <-- hier/toto
                           \
                           \
                           '--------- avant-hier/toto
                           '--------- avant-hier/toto


current/toto.tmp --> nouveau contenu</code>
current/toto.tmp --> nouveau contenu</span>
* enfin, <code>toto.tmp</code> est renommé en <code>toto</code> :
* enfin, <span class="code">toto.tmp</span> est renommé en <span class="code">toto</span> :
<code>                contenu <-- hier/toto
<span class="code">                contenu <-- hier/toto
                           \
                           \
                           '--------- avant-hier/toto
                           '--------- avant-hier/toto


current/toto --> nouveau contenu</code>
current/toto --> nouveau contenu</span>
* on obtient bien 2 versions différentes, celle d'hier et d'avant-hier (le fichier n'avait alors pas changé), et celle d'aujourd'hui.
* on obtient bien 2 versions différentes, celle d'hier et d'avant-hier (le fichier n'avait alors pas changé), et celle d'aujourd'hui.


Ainsi j'ai toujours les backup des 8 (réglable par la variable <code>KEEP</code> ci-dessus) derniers jours disponible. Je peux retrouver les dernières versions d'un fichier en cas de problème.
Ainsi j'ai toujours les backup des 8 (réglable par la variable <span class="code">KEEP</span> ci-dessus) derniers jours disponible. Je peux retrouver les dernières versions d'un fichier en cas de problème.


== Spécificités de la sauvegarde système ==
== Spécificités de la sauvegarde système ==

Dernière version du 21 mai 2012 à 23:00


Sauvegarder son système, ses données

Sauvegarder son système ou ses données : que garder ? Quels logiciels utiliser ? Sur quel support ?

Que sauvegarder

Avant d'entamer les différentes manières et d'apprendre les divers outils permettant d'effectuer une sauvegarde, il est tout d'abord nécessaire de définir ce que l'on souhaite sauver. On peut soit choisir de sauvegarder uniquement ses données importantes (plus simple à mettre en place), soit son système entier.

Les types de sauvegardes

Il existe deux types de sauvegardes :

  • Totales : avec une sauvegarde totale, on sauve l'intégralité des données que l'on souhaite garder
  • Partielles : Une sauvegarde partielle suit une sauvegarde totale ou une sauvegarde partielle. Ici, nous allons seulement sauver les nouveaux fichiers ou ceux qui ont été modifiés depuis la dernière sauvegarde. Cette sauvegarde est beaucoup plus rapide, mais peut demander beaucoup de manipulations en cas de restauration. Pour restaurer, il faudra partir de la dernière sauvegarde totale, puis passer dans l'ordre chronologique les sauvegardes partielles.

Les médias

Les médias possibles sont :

  • CD/DVD : ils permettent de stocker les données par tranches de 650 Mo, 700 Mo, 4.7 Go ou 8 Go. Ces médias optiques ont un support chimique, ce qui implique une déterioration avec le temps. Un CD gravé aujourd'hui et stocké dans son boîtier ne sera peut être pas lisible dans 10 ans!
  • disque dur : ce disque peut être interne, usb, un disque réseau (NAS), ou un partage réseau (lufs/nfs/samba/ftp). Il présente d'avoir l'avantage d'une capacité plus importante, voire la possibilité d'externaliser ses sauvegardes (utile si la maison brûle).
  • Clé usb : leurs capacités augmentent et peuvent être supérieures à celle d'un CD. Un de ses avantages est que c'est un média de stockage peu cher qui peut fonctionner sur d'anciens ordinateurs (pas besoin de graveur). C'est un des médias les plus pratiques : rapidité d'écriture par rapport à un CD (pas d'image à faire), peu encombrant, mais il est limité en cycles de lecture/écriture.

Le choix du média sera dicté en partie selon la quantité de données à sauvegarder.

Les outils de sauvegarde

Avant de sauvegarder, il faut commencer par recenser ce que l'on souhaite garder. De plus, l'idée serait que les utilisateurs n'aient aucun fichier en cours de modification au moment de la sauvegarde. On ne pourra pas garantir, le cas contraire, que son fichier sera bien sauvegardé.

la commande tar

La commande tar permet de sauvegarder un ensemble de fichiers dans une archive qui peut être compressée. Les fichiers ne seront donc pas directement lisibles.

Sauvegarde avec tar

Présentation des options

Pour créer une archive, il suffit d'utiliser la commande: tar c nom_archive [fichier repertoire1] [fichier ou repertoire2]... Différentes options peuvent s'avérer utiles :

  • -v : mode verbeux, liste les fichiers qui sont en cours d'archivage
  • -z (resp. j) : permet de compresser l'archive avec le format gzip (resp. bzip2). Le format bzip2 permet d'avoir des fichiers plus petits au coût d'un traitement plus long
  • --preserve : permet de sauvegarder les permissions. De plus, lors de la restauration, les fichiers seront "détarrés" dans le même ordre
  • --same-owner : permet de sauvegarder l'appartenance du fichier
  • -T fichier : fichier est un fichier où chaque ligne correspond à un fichier ou répertoire à sauvegarder
  • -X fichier : fichier est un fichier où chaque ligne correspond à un fichier ou répertoire à exclure parmis les répertoires à sauvegarder
  • --exclude=fichier : fichier sera exclu de la sauvegarde
  • -N date : permet de ne sauvegarder que les fichiers postérieurs à la date définie. La date doit être fournie sous la forme AAAA-MM-JJ HH:MM:SS". On obtient se format grâce à la commande date "+%Y:%m:%d %H:%M:%S"
  • --totals : affiche le nombre d'octets écrits lors de la sauvegarde
  • -g fichier : permet d'effectuer des sauvegardes incrémentales, en se basant sur un fichier de status. Ce fichier est soit utilisé (sauvegarde incrémentale), soit créé (sauvegarde full). Attention, cette option n'est valable que pour les versions GNU!

ATTENTION: Il faut toujours exclure les répertoires /dev et /proc! Sous linux, tout est fichier. Le matériel est identifié dans /dev par des fichiers spéciaux. Vouloir sauvegarder /dev via tar est vain. Dans /proc, il y a un fichier spécial, /proc/kcore, qui correspond à la RAM de l'ordinateur. Je n'ai pas fait le test, mais le "restaurer" est à vos risques et périls (kernel panic).

Exemple de sauvegarde de données

Voici un petit script permettant de mettre en place une sauvegarde totale et/ou différentielle de données :

#!/bin/bash
# Options
# -d : sauvegarde differentielle
# -h : affiche les options possibles
# Si on demande l'aide, on l'affiche, et on sort
if [ "$1" = "-h" ] ; then
 echo "Usage : $0 : sauvegarde totale"
 echo "Usage : $0 -d : sauvegarde différentielle"
 echo "Usage : $0 -h : cette aide"
fi
# Initialisation des variables
DATE=$(date "+%Y-%m-%d %H:%M:%S")
TYPE="FULL"
REP=/backup
FICHIER_EXCLUDE=/etc/save.exclude
FICHIER_INCLUDE=/etc/save.include
FICHIER_STATUS=/etc/save.state
COMPRESSION=9
# Si le script est appelé avec l'option "-d", alors on fait une sauvegarde   différentielle
if [ "$1" = "-d" ] ; then
    TYPE="INCR"
    tar cP --atime-preserve -g $FICHIER_STATUS --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION >  ${REP}/save-INCR-${DATE}.tgz
# Sinon, on fait une sauvegarde totale
else
    rm -f $FICHIER_STATUS
    tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > ${REP}/save-FULL-${DATE}.tgz
fi
Exemple de sauvegarde système

Le script suivant permet de faire une sauvegarde système, plus complet, a pour but de faire une sauvegarde système sur un serveur NFS. Il utilise un fichier de configuration. Le prérequis est de renseigner le fichier /etc/save.conf et d'utiliser udev.

Le fichier save.conf doit être de la forme :

EXCLUDE="/repertoire1 /repertoire2"
# Le reste est optionnel
#COMPRESSION=1
#SERVEUR="10.0.0.2:/path
#MONTAGE="/mnt/nfs"
#INCLUDE="/toto"

Et le script :

#!/bin/sh
# Options
# -d : sauvegarde differentielle
# -h : affiche les options possibles
# Si on demande l'aide, on l'affiche, et on sort
if [ $1 = "-h" ] ; then
 echo "Usage : $0 : sauvegarde totale"
 echo "Usage : $0 -d : sauvegarde différentielle"
 echo "Usage : $0 -h : cette aide"
fi
PID=$$
# On donne une priorité faible au processus pour ne pas dégrader les  performances des autres applications
renice +19 $PID
. /etc/save.conf
MONTAGE=${MONTAGE:="/tmp/save.$PID"}
SERVEUR=${SERVEUR:="10.0.0.1:/backup"}
COMPRESSION=${COMPRESSION:=9}
NOM=$(hostname)
CONFIGURATION=${MONTAGE}/${NOM}.conf
DATE="$(date "+%Y-%m-%d %H:%M:%S")"
FICHIER_EXCLUDE=/tmp/save.$PID.exlude
FICHIER_INCLUDE=/tmp/save.$PID.include
FICHIER_STATUS=/etc/save.state
LVMVERSION=1
affiche_action() {

echo -e "$1 ........... \c"

}
affiche_resultat() {

if [ $1 = 0 ] ; then echo -e '[\c' tput setaf 2 echo -e "OK\c" tput setaf 7 echo -e ']' return 0 else echo -e '[\c' tput setaf 1 echo -e "KO\c" tput setaf 7 echo -e ']' return 1 fi

}
quit() {

affiche_action "Nettoyage en cours" rm -f $FICHIER_EXCLUDE rm -f $FICHIER_INCLUDE umount $MONTAGE rmdir $MONTAGE affiche_resultat $? exit $1

}
# Montage du partage nfs
affiche_action "Montage du partage NFS vers $SERVER"
mkdir $MONTAGE
mount -t nfs $SERVER $MONTAGE
affiche_resultat $? || quit 1
# Sauvegarde des donnees de partitionnement
affiche_action "Sauvegarde du partitionnement"
echo "[disks]" > $CONFIGURATION
/sbin/fdisk -l | tr '*' ' ' | awk '/^\/dev/ {print $1,$2,$3,$5}' >>   $CONFIGURATION
affiche_resultat $? || quit 1
echo "[bootdisk]" >> $CONFIGURATION
fdisk -l | awk '/^\/dev\/.*\*/ {print $1}' >> $CONFIGURATION
# Sauvegarde du lvm : PV, VG, LV et version du LVM
affiche_action "Sauvegarde des groupes de volumes du LVM"
echo "[LVM-VG]" >> $CONFIGURATION
liste=$(pvscan | grep -o 'PV.*/dev/.*VG.*' | tr -d '"' | sed 's,^.*PV   \(/dev/[^ ]*\).* VG \([^ ]*\).*,\1 \2,')
liste2=$(echo $liste | grep -o '/dev/[^ ]*')
for element in $liste2 ; do
       LVM=1
       $REP/bin/lvm.static pvscan 2>/dev/null | grep $element 2>/dev/null |  grep -q lvm2
       [ $? = 0 ] && LVM=2
       echo $(echo $liste | grep -o "$element [^ ]*") $LVM >> $CONFIGURATION
done
affiche_resultat $? || quit 1
affiche_action "Sauvegarde des volumes logiques du LVM"
echo "[LVM-LV]" >> $CONFIGURATION
for volume in $(lvscan | grep -o '"/dev[^"]*"' | tr -d '"') ; do

extend=$(lvdisplay $volume | awk '/Allocated LE/ {print $3}') echo "$volume $extend" >> $CONFIGURATION

done
affiche_resultat $? || quit 1
# Sauvegarde des labels
affiche_action "Sauvegarde des labels des partitions"
echo "[labels]" >> $CONFIGURATION
for partition in $(/sbin/fdisk -l | grep -o '^/dev/[^ ]*') ; do

label=$(/sbin/e2label $partition 2>/dev/null) echo "$partition=$label" >> $CONFIGURATION

done
affiche_resultat $? || quit 1
# Sauvegarde des points de montage
affiche_action "Sauvegarde des points de montage"
echo "[montage]" >> $CONFIGURATION
mount | awk '/ext[23]/ {print $1,$3}' >> $CONFIGURATION
affiche_resultat $? || quit 1
# Sauvegarde de la hierarchie exclue
affiche_action "Creation de la liste des repertoires exclus a recontruire"
echo "[hierarchie]" >> $CONFIGURATION
rm -f $FICHIER_EXCLUDE
# On exclu les partages NFS et les montages loop
mount | awk '/type nfs/ { print $3}' >> $FICHIER_EXCLUDE
mount | awk '/loop=/ { print $3}' >> $FICHIER_EXCLUDE
# Rajout des répertoires à exclure par défaut
[ -d /media ] && EXCLUDE="/media $EXCLUDE"
EXCLUDE="/mnt /sys /dev /tmp /proc /var/run /var/log /var/lock /var/spool  /var/tmp /var/cache $EXCLUDE"
for rep in $EXCLUDE ; do

case $rep in /mnt) echo "/mnt" >> $CONFIGURATION for rep in $(ls -F /mnt | tr -d '/') ; do [ -d /mnt/$rep ] && echo "/mnt/$rep" >> $CONFIGURATION done ;; /media) echo "/media" >> $CONFIGURATION [ -d /media ] && for rep in $(ls -F /media | tr -d '/')  ; do [ -d /media/$rep ] && echo "/media/$rep" >> $CONFIGURATION done ;; /dev) echo "/dev" >> $CONFIGURATION ;; /tmp) echo "/tmp" >> $CONFIGURATION ;; /proc) echo "/proc" >> $CONFIGURATION ;; /sys) echo "/sys" >> $CONFIGURATION ;; /var*) echo "/var" >> $CONFIGURATION ls -R $rep | grep ':$' | tr -d ':' >> $CONFIGURATION ;; /usr/src) echo $rep >> $CONFIGURATION ;; /home) echo "/home" >> $CONFIGURATION for rep in $(ls -F /home | tr -d '/') ; do [ -d /home/$rep ] && echo "/home/$rep" >> $CONFIGURATION done ;; /usr*) ls -R $rep | grep ':$' | tr -d ':' >> $CONFIGURATION ;; /bin*) ls -R $rep | grep ':$' | tr -d ':' >> $CONFIGURATION ;; /sbin*) ls -R $rep | grep ':$' | tr -d ':' >> $CONFIGURATION ;; /lib*) ls -R $rep | grep ':$' | tr -d ':' >> $CONFIGURATION ;; /boot*) ls -R $rep | grep ':$' | tr -d ':' >> $CONFIGURATION ;; *) [ -d $rep ] && echo $rep >> $CONFIGURATION ;; esac echo $rep >> $FICHIER_EXCLUDE

done
affiche_resultat $? || quit 1
echo '*/lost+found' >> $FICHIER_EXCLUDE
# Sauvegarde de grub
affiche_action "Sauvegarde de grub"
echo "[GRUB]" >> $CONFIGURATION
cat /boot/grub/menu.lst | grep '^[^#].*root (hd' | head -n 1 | grep -o  'root.*' >> $CONFIGURATION
affiche_resultat $? || quit 1
# Si l'option -d est passee en parametre, on fait une sauvegarde differentielle
INCLUDE=${INCLUDE:=/}
rm -f $FICHIER_INCLUDE
for rep in $INCLUDE ; do

echo $rep >> $FICHIER_INCLUDE

done
if [ $# -ge 1 ] && [ $1 = "-d" ] ; then

affiche_action "Sauvegarde du systeme sur $SERVEUR/${NOM}-INCR-${DATE}" tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > $MONTAGE/${NOM}-INCR-${DATE}.tar.gz affiche_resultat $? || quit 1

else

affiche_action "Sauvegarde du systeme sur $SERVEUR/${NOM}-FULL-${DATE}"

       rm -f $FICHIER_STATUS

tar cP -g $FICHIER_STATUS --atime-preserve --preserve --same-owner --totals -T $FICHIER_INCLUDE -X $FICHIER_EXCLUDE | gzip -$COMPRESSION > $MONTAGE/${NOM}-FULL-${DATE}.tar.gz affiche_resultat $? || quit 1 fi

# Sauvegarde de MAKEDEV qui se trouve dans /dev
affiche_action "Sauvegarde de MAKEDEV"
[ -f /dev/MAKEDEV ] && cp /dev/MAKEDEV $MONTAGE/
affiche_resultat 0
quit 0

Restauration avec tar

Présentation de la commande

Pour restaurer un tar, il suffit d'utiliser la commande: tar x nom_archive Là encore, il existe diverses options:

  • -v : mode verbeux : afficher les fichiers en cours d'extraction
  • -z (resp. j) : permet de décompresser l'archive compressée avec le format gzip (resp. bzip2)
  • --atime-preserve : permet de ne pas modifier la date d'accès du fichier restauré
  • -C repertoire : permet de désarchiver dans le répertoire mentionné
  • --preserve : permet de restaurer les permissions. De plus, lors de la restauration, les fichiers seront "détarrés" dans le même ordre
  • --same-owner : permet de restaurer l'appartenance du fichier
  • --numeric-owner : utilise les numéros pour les appartenances group/utilisateur. Petit exemple vécu : restauration à partir d'un live-cd. Sur le live-cd, l'utilisateur gdm avait comme uid 32. Sur la distrib, gdm correspondait à 42, et 32 à rpc. Lors du reboot, gdm refusait de se lancer car le répertoire /var/gdm ne lui appartenait pas. Il est donc préférable de restaurer les uid/gid au lieu d'utiliser les noms.


Voici un exemple de commande pour restaurer une archive : tar zxvf --atime-preserve --preserve --same-owner --numeric-owner /backup/archive.tgz

la commande rsync

rsync permet de synchroniser des répertoires/fichiers destinations par rapport à des répertoires/fichiers sources. La synchronisation se fait soit en local, soit sur une machine distante. Il est possible de demander à rsync d'utiliser ssh afin de crypter les transmissions.

La commande rsync

Pour l'utiliser il suffit d'utiliser: rsync [options] source(s) destination

Les options :

  • -v : mode verbeux
  • -a : mode archive (correspond à -rlptgoD)
  • -q : supprime les messages d'information (mais pas d'erreur)
  • -r : récursif (pour les répertoires)
  • -l : copie les liens symboliques en liens symboliques
  • -p : préserve les permissions
  • -o : garde le propriétaire (option disponible uniquement pour root)
  • -g : garde le groupe
  • --device : garde les fichiers de périphériques (uniquement pour root, et utile pour une sauvegarde système)
  • -H : garde les hardlink. Attention, cette option est coûteuse en ressources!
  • --specials : garde les fichiers spéciaux
  • -t : garde l'horodatage
  • -e remoteshell : spécifie le shell distant à utiliser (ssh par exemple)
  • --delete : supprime sur la destination les fichiers qui n'existent pas sur la source
  • --numeric-ids : ne fait pas la conversion uid/gid en user/group.
  • -z : compresse pendant la transmission
  • --exclude=PATTERN : définit un motif à exclure (par exemple */lost+found)
  • --exclude-from fichier : lit les motifs dans le fichier
  • --bwlimit=VALEUR : limit la bande passante à VALEUR Ko

Bien entendu, man rsync vous donnera toutes les options disponibles

Exemple de sauvegarde incrémentale avec rsync

Côté machine à sauvegarder

Dans la crontab de la machine à sauvegarder, vers 22h00, on lance le script suivant :

#!/bin/sh
# répertoires à sauvegarder
DIRS="/home/jice /home/fred /etc /root /boot /var/lib/mysql /var/spool/mail"
# fichier contenant les fichiers à exclure de la sauvegarde
# voir EXCLUDE PATTERNS dans rsync(1)
EXCLUDEFILE="/home/jice/bin/excludes"
OPTIONS="-avz -e ssh"
OPTIONS="$OPTIONS --exclude-from $EXCLUDEFILE --bwlimit=50"
OPTIONS="$OPTIONS $*"
rsync $OPTIONS $DIRS jice@mon.serveur.net:backup/current
# copie du fichier "flag" pour dire au serveur que le backup a été fait
scp /home/jice/bin/backup_done jice@mon.serveur.net:~

Ce script fait un backup vers le répertoire backup/current du serveur (nommé mon.serveur.net) ; à la fin, il copie un fichier (vide) backup_done à la racine de mon compte sur le serveur, afin de dire au serveur que le backup a bien été fait.

PS : voici un exemple de fichier excludes

# excludes pour le backup sur zowie
jice/tmp*
jice/multimedia/video/*
jice/compil/*
fred/compil/*
*/.local/share/Trash/*
*/.kde/share/config/session/konqueror*
*/temp/*
*/tmp/*
*/cache/*
*/Cache/*
*/.thumbnails/*
*/.xvpics/*
*/.kde/tmp-*
*/.mcop/*
*/.ncftp/trace*
*/.nx/*
*.o
*.so
*.mp3
*.avi
*.rar
*.ace

Notez que ce fichier peut contenir ou bien le nom complet d'un fichier, ou bien un "morceau" de nom de fichier avec des étoiles comme caractère joker. Pour plus d'information, tapez dans une console : man rsync et cherchez EXCLUDE PATTERNS.

Côté serveur de sauvegarde

Côté serveur, j'ai ce script qui fait une rotation des backups (en cron tous les midi) :

#!/bin/sh
if [ -f ~/backup_done ]; then
       KEEP=8
       DIR=~/backup
       # arborescence :
       # ~/backup/2006-04-03
       # ~/backup/2006-04-04
       # ~/backup/2006-04-05
       # ~/backup/current
       # calcule date du jour
       DATE=`date --date=yesterday "+%Y-%m-%d"`
       # crée le répertoire pour les backups du jour
       mkdir $DIR/$DATE
       # supprime les vieux directories
       ls -d $DIR/2* | sort | head --lines=-$KEEP | xargs rm -rf
       # copie (hard links) les données
       cp -al $DIR/current/* $DIR/$DATE
       # supprime le fichier flag
       rm ~/backup_done
       # on fait le rsync ensuite
fi

Si le backup a été fait (présence du fichier backup_done, il effectue une rotation des backups.
En utilisant le cp avec les hard links, on ne copie pas réellement les fichiers, mais on crée un deuxième fichier qui pointe vers le contenu du premier (donc on peut avoir autant de hardlink qu'on veut sur le même fichier, la place disque utilisée n'est toujours que de la taille d'un seul fichier).
Rsync lorsqu'il enverra, lors de la prochaine sauvegarde, un fichier modifié, utilisera un nom différent temporaire, avant de le renommer vers son nom normal. Ainsi, il ne va pas écraser le contenu du fichier hardlinké, car à la fin de la copie du fichier, Rsync supprime le fichier, puis renomme le fichier temporaire vers son nom normal.

A ce moment là, on a sur le serveur 2 versions du même fichier : la version courante qui vient d'être sauvegardée dans ~/backup/current/repertoire/fichier et la version précédente qui a été copiée par le script ci-dessus dans ~/backup/<la date du dernier backup>/repertoire/fichier.

Plus d'explications :

  • on a deux fichiers current/toto et hier/toto qui pointent vers le même contenu. Ces 2 fichiers (ou plus) on été obtenus suite au script de rotation, par la copie avec hardlinks. On a donc :

current/toto --> contenu <-- hier/toto

                              \
                               '--------- avant-hier/toto

  • si le fichier a été modifié, rsync va envoyer le nouveau fichier sous un nom temporaire toto.tmp (par exemple). On a donc :

current/toto --> contenu <-- hier/toto

                              \
                               '--------- avant-hier/toto

current/toto.tmp --> nouveau contenu

  • ensuite, rsync supprime current/toto On obtient, par la magie des hardlinks :

contenu <-- hier/toto

                         \
                          '--------- avant-hier/toto

current/toto.tmp --> nouveau contenu

  • enfin, toto.tmp est renommé en toto :

contenu <-- hier/toto

                         \
                          '--------- avant-hier/toto

current/toto --> nouveau contenu

  • on obtient bien 2 versions différentes, celle d'hier et d'avant-hier (le fichier n'avait alors pas changé), et celle d'aujourd'hui.

Ainsi j'ai toujours les backup des 8 (réglable par la variable KEEP ci-dessus) derniers jours disponible. Je peux retrouver les dernières versions d'un fichier en cas de problème.

Spécificités de la sauvegarde système

Si l'on veut effectuer une sauvegarde système, il est nécessaire de prendre en compte les points suivants:

  • faire une sauvegarde en gardant les uid/gid
  • ne pas sauvegarder les répertoires inutiles (/tmp, /dev, /proc, /sys, le contenu des points de montages hors disques locaux (nfs, cdrom,...)) On peut également ne pas sauvegarder le contenu de /var/tmp, /var/cache, /var/lock, /var/run, /var/spool. Attention, il est important de garder la hiérarchie de ces répertoires!
  • garder la table des partitions, avec le label des partitions si il y en a un (commande 'e2label')
  • sauvegarder les informations de lvm (l'idéal étant de pouvoir utiliser lvmcfgbackup et lvmcfgrestore. Sinon, ce n'est pas la taille de chaque volume qu'il faut sauvegarder, mais le nombre de Logical Extends. En spécifiant une taille, celle-ci sera arrondie pour avoir un nombre de LE fixe. Ce nombre ne sera pas forcément identique que celui utilisé lors de la création, et empêchera donc de restaurer le système de manière identique).
  • arrêter autant que faire se peut les services qui tournent.

Les conseils

  • Vérifier la sauvegarde après l'avoir faite : test md5 par exemple. Ce n'est pas lorsqu'on en aura besoin qu'il faut se rendre compte que le graveur ne gravait plus!
  • Tester la restauration
  • Vérifier régulièrement (tous les ans) que l'on arrive bien à relire sa sauvegarde (voire refaire une sauvegarde sur un média neuf tous les 2 ans par exemple)

Les outils graphiques / semi-graphiques

  • mondorescue
  • kbackup
  • amanda backup
  • bacula
  • backuppc



@ Retour à la rubrique Administration système

Copyright

© 2006 Oudoubah

Creative Commons License
Creative Commons Attribution iconCreative Commons Share Alike icon
Ce document est publié sous licence Creative Commons
Attribution, Partage à l'identique 4.0 :
https://creativecommons.org/licenses/by-sa/4.0/