User Tools

Site Tools


notes:lvm-automate-snapshot

Automatisation des snapshots LVM comme solution de backup

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é.

Snapshots de LVM

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ù :

  • LVVolume est le device du volume, comme /dev/LVM/SRV
  • nomdusnapshot est le nom du snapshot
  • -l 10%ORIGIN est la taille du snapshot, dans cet exemple elle sera de 10% par rapport au volume d’origine. On peut lui indiquer une grandeur réelle avec -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.

Mise en place d’une stratégie de sauvegarde

La stratégie répond à 2 objectifs:

  • La mise en place de sauvegardes automatiques, dédiée aux volumes data, comme le répertoire /home et le répertoire /srv .
  • La mise en place de points de sauvegardes, c’est une sauvegarde manuelle, faite lors d’opérations de maintenance ou d’upgrade du système. Elle s’effectue sur les répertoires /, /usr, /opt

Script de backup

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"

Fichiers de configuration

Ce script a besoin de fichiers de configuration :

  • Le premier, général, détermine la destination des sauvegardes :
# /etc/lvbackup.conf/lvbackup.conf
BACKUPDEV=/dev/vol
  • Le deuxième, spécifique au volume que l’on souhaite sauvegarder (XXX doit être le nom du volume à sauvegarder, la casse est importante):
# /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.

Paramétrage typique

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

Sauvegarde manuelle

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

Automatisation de la sauvegarde

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

Restauration

Il n’y a pas de script de restauration, car le besoin de restauration peut être de plusieurs nature

  • soit une restauration complète: créer un autre volume, puis recopier le backup dans celui-ci, et remplacer l’ancien volume par le nouveau.
  • soit une restauration partielle: après extraction de l’archive, remplacer le contenu d’un répertoire par celui de l’archive
notes/lvm-automate-snapshot.txt · Last modified: 2025/02/19 10:59 by 127.0.0.1