Un des intérêts de LVM, est de pouvoir créer des snapshots de volume sans perturber le fonctionnement de la machine, sans interruption de services. A l’aide de simples scripts, l’automatisation des backups en est grandement facilité.
Cet article présente un script bash de backup minimaliste. Ce n’est qu’un exemple qui peut être grandement amélioré.
Les snapshots permettent de créer un cliché d’un volume à instant t. C’est une opération rapide, même pour les volumes importants et ne nécessite pas forcément beaucoup de ressource disque.
La création de snapshot s’effectue par la commande suivante :
lvcreate -n nomdusnapshot -l 10%ORIGIN -s LVVolume
où :
-l 100M
par exemple.La taille du snapshot est la taille allouée pour enregistrer les différences entre le snapshot et le disque d’origine.
Si la quantité de modification dépasse la quantité allouée, le snapshot ne sera plus utilisable. Mais on peut celui-ci par un lvextend
avant qu’elle atteigne sa limite.
Le volume créé, peut-être monté comme n’importe quelle autre volume.
La stratégie répond à 2 objectifs:
/home
et le répertoire /srv
./
, /usr
, /opt
Le script utilise bzip2, :
apt-get install bzip2
Contenu du script /sbin/lvbackup (attention, le nom du script est important)
#!/bin/bash [ -z "${1}" ] && echo "Missing LVNAME" && return 0 || LVNAME=${1} GLOBALCONFFILE="/etc/lvbackup.conf/lvbackup.conf" LVCONFFILE="/etc/lvbackup.conf/$LVNAME.conf" PRE_SNAP_CMD=/etc/lvbackup.conf/$LVNAME-pre-snap POST_SNAP_CMD=/etc/lvbackup.conf/$LVNAME-post-snap if [ ! -f "$GLOBALCONFFILE" ]; then echo "Missing configuration file $GLOBALCONFFILE !" exit 1 fi if [ ! -f "$LVCONFFILE" ]; then echo "Missing configuration file $LVCONFFILE !" exit 1 fi . $GLOBALCONFFILE . $LVCONFFILE LVVOLUME=/dev/$VGNAME/$LVNAME case `basename $0` in lvautobackup) [ -z "$HISTOSIZE" ] && HISTOSIZE=5 [ -z "${2}" ] && SNAPTAG=AUTOBACKUP-$LVNAME- || SNAPTAG=AUTOBACKUP-${2}-$LVNAME- ;; *) unset HISTOSIZE [ -z "${2}" ] && SNAPTAG=SAVE-$LVNAME- || SNAPTAG=${2}-$LVNAME- ;; esac SNAPNAME=$SNAPTAG$(date -u +%Y.%m.%d-%H.%M.%S) if [ ! -e "$LVVOLUME" ]; then echo "Volume not found : $LVVOLUME!" exit 1 fi [ -z "$TARFLAGS" ] || TARFLAGS="" for t in ${EXCLUDE[*]} do TARFLAGS="$TARFLAGS --exclude=/mnt/$SNAPNAME/snap$t" done logger "$(date -u +%Y.%m.%d-%H.%M.%S) - $LVVOLUME - Start backup " [ -f "$PRE_SNAP_CMD" ] && $PRE_SNAP_CMD lvcreate -n $SNAPNAME -l 10%ORIGIN -s $LVVOLUME [ -f "$POST_SNAP_CMD" ] && $POST_SNAP_CMD mkdir /mnt/$SNAPNAME mkdir /mnt/$SNAPNAME/snap mkdir /mnt/$SNAPNAME/bckup echo "mounting $BACKUPDEV on /mnt/$SNAPNAME/bckup" mount $BACKUPDEV /mnt/$SNAPNAME/bckup mount /dev/$VGNAME/$SNAPNAME /mnt/$SNAPNAME/snap logger "$(date -u +%Y.%m.%d-%H.%M.%S) - $LVVOLUME - Begin compression" tar -cjv $TARFLAGS -f /mnt/$SNAPNAME/bckup/$SNAPNAME.bz2 /mnt/$SNAPNAME/snap [ -z "$HISTOSIZE" ] || ls -rt /mnt/$SNAPNAME/bckup/$SNAPTAG*.bz2 | head -n -$HISTOSIZE | xargs rm umount /mnt/$SNAPNAME/bckup umount /mnt/$SNAPNAME/snap lvremove -f /dev/$VGNAME/$SNAPNAME rm -rf /mnt/$SNAPNAME logger "$(date -u +%Y.%m.%d-%H.%M.%S) - $LVVOLUME - backup successful as $BACKUPDEV/$SNAPNAME.bz2"
Ce script a besoin de fichiers de configuration :
# /etc/lvbackup.conf/lvbackup.conf BACKUPDEV=/dev/vol
# /etc/lvbackup.conf/XXX.conf # XXX Backup configuration # Groupe de volume (VG) VGNAME=LVM # Taille de l'historique des backup pour les sauvegardes automatiques HISTOSIZE=3 # Liste des répertoires à ignorer EXCLUDE=( ....)
Optionnellement, on peut ajouter deux scripts d’exécution de tache. Le premier qui opère juste avant le snapshot, et le second juste après :
XXX-pre-snap et XXX-post-snap
Ces deux scripts serviront à effectuer des opérations visant à obtenir un snapshot cohérent au niveau des données. Typiquement, si une base de données est hébergée sur le volume, il convient de flusher et de locker les tables pendant le snapshot. L’impacte de cette opération au niveau des clients est très faible car le snapshot est rapide.
Pour les exemples ci-dessous, je prendrais comme architecture de référence celle décrite dans le sujet : Modèle de Serveur Debian Raid5 et LVM passe partout
Créations d'un lien symbolique pour les sauvegardes automatiques :
ln -s /sbin/lvbackup /sbin/lvautobackup
Création de volume de stockage des backups :
# lvcreate -L 200G -n BACKUP LVM # mkfs.ext3 /dev/LVM/BACKUP
Un petit tour sur les volumes existants :
# lvs LV VG Attr LSize Origin Snap% Move Log Copy% Convert BACKUP LVM -wi-a- 279,39g HOME LVM -wi-ao 93,13g OPT LVM -wi-ao 46,56g ROOT LVM -wi-ao 18,62g SRV LVM -wi-ao 93,13g TMP LVM -wi-ao 952,00m USR LVM -wi-ao 46,56g VAR LVM -wi-ao 18,62g
Création des fichiers de configuration
# /etc/lvbackup.conf/lvbackup.conf BACKUPDEV=/dev/LVM
# /etc/lvbackup.conf/SRV.conf # SRV Backup configuration # Groupe de volume (VG) VGNAME=LVM # Taille de l'historique des backup pour les sauvegardes automatiques HISTOSIZE=10
# /etc/lvbackup.conf/HOME.conf # HOME Backup configuration # Groupe de volume (VG) VGNAME=LVM # Taille de l'historique des backup pour les sauvegardes automatiques HISTOSIZE=10
# /etc/lvbackup.conf/USR.conf # USR Backup configuration # Groupe de volume (VG) VGNAME=LVM
# /etc/lvbackup.conf/ROOT.conf # ROOT Backup configuration # Groupe de volume (VG) VGNAME=LVM EXCLUDE=( "/lib" "/tmp" "/var" "/mnt" "/opt" "/home" "/srv" "/media" "/dev" "/boot" "/proc" "/sys" "/root")
# /etc/lvbackup.conf/OPT.conf # OPT Backup configuration # Groupe de volume (VG) VGNAME=LVM
Le fichier de configuration du Root est particulier car il ne doit pas prendre en compte les volumes attachés, ni les répertoires temporaires et virtuels.
La base de données est hébergé sur /srv/mysql-data, pour garantir un état stable de celle-ci il faut ajouter deux scripts :
/etc/lvbackup.conf/SRV-pre-snap:
#!/bin/bash DATABASES=`echo "SHOW DATABASES;" | mysql --skip-column-names -u root --password=admin` for DB in $DATABASES; do echo "Flush database $DB" echo "FLUSH TABLES WITH READ LOCK;" | mysql $DB -u root --password=admin done
et /etc/lvbackup.conf/SRV-post-snap
#!/bin/bash DATABASES=`echo "SHOW DATABASES;" | mysql --skip-column-names -u root --password=admin` for DB in $DATABASES; do echo "Unlock database $DB" echo "UNLOCK TABLES;" | mysql $DB -u root --password=admin done
Il convient pour ce genre de script, de créer un compte spécifique pour la maintenance avec les droits appropriés pour effectuer cette tache.
Définir les attributs des fichiers :
# chmod 755 /sbin/lvbackup # chmod 755 /sbin/lvautobackup # chmod 755 /etc/lvbackup.conf/SRV-pre-snap # chmod 755 /etc/lvbackup.conf/SRV-post-snap
Pour valider l'installation sauvegarder la configuration de base :
# lvbackup OPT ; lvbackup ROOT ; lvbackup USR
un petit coup d’oeil sur le répertoire de backup pour voir si tout s’est passé normalement :
# mkdir /mnt/backup # mount /dev/LVM/BACKUP /mnt/backup/ # ls -al /mnt/backup/ total 144772 drwxr-xr-x 2 root root 4096 3 avril 11:34 . drwxr-xr-x 3 root root 4096 3 avril 11:39 .. -rw-r--r-- 1 root root 201 3 avril 11:34 SAVE-OPT-2013.04.03-09.34.17.bz2 -rw-r--r-- 1 root root 4641326 3 avril 11:34 SAVE-ROOT-2013.04.03-09.34.18.bz2 -rw-r--r-- 1 root root 143274574 3 avril 11:37 SAVE-USR-2013.04.03-09.34.43.bz2 root@localhost:~# umount /mnt/backup/ root@localhost:~# rm -r /mnt/backup
On peut ajouter un tag spécifique comme aide mémoire par exemple:
root@localhost:~# lvbackup OPT ADD-REDMINE
Pour les répertoires HOME on programme une sauvegarde journalière tandis que /srv
aura une sauvegarde journalière et une toute les heures.
Ajouter dans le fichier /etc/crontab :
00 * * * * root /sbin/lvautobackup SRV HOURLY 15 1 * * * root /sbin/lvautobackup SRV 15 1 * * * root /sbin/lvautobackup HOME
attendre l’heure passée pour vérifier la configuration :
# mkdir /mnt/backup # mount /dev/LVM/BACKUP /mnt/backup/ # ls -al /mnt/backup/total 144920 drwxr-xr-x 2 root root 4096 3 avril 12:00 . drwxrwxrwt 3 root root 4096 3 avril 12:00 .. -rw-r--r-- 1 root root 147329 3 avril 12:00 AUTOBACKUP-HOURLY-SRV-2013.04.03-10.00.01.bz2 -rw-r--r-- 1 root root 201 3 avril 11:34 SAVE-OPT-2013.04.03-09.34.17.bz2 -rw-r--r-- 1 root root 4641326 3 avril 11:34 SAVE-ROOT-2013.04.03-09.34.18.bz2 -rw-r--r-- 1 root root 143274574 3 avril 11:37 SAVE-USR-2013.04.03-09.34.43.bz2 # umount /mnt/backup/ # rm -r /mnt/backup
Il n’y a pas de script de restauration, car le besoin de restauration peut être de plusieurs nature