Juil 23 2008

Sauvegarde Mysql Ultra-rapide avec LVM

Publié par à 12:00 sous Mysql,Sauvegarde

C’est toujours une bonne idée de respecter les deux points suivants lors de la sauvegarde de bases de données. La backup doit être:
– consistante
– rapide
 
La consistance est réalisée facilement en mettant un read lock sur toutes les tables avant tout. Cependant, ceci n’est pas toujours mis en application, et mênera sûrement à un problème d’intégrité.
Une fois le verrou établi, la sauvegarde doit être réalisée le plus vite possible, toutes les instructions d’écritures étant mises en attente dans la queue par le lock.


Mysql et les Snapshots LVM

Voici les principales méthodes pour réaliser une sauvegarde:

  • mysqldump, fourni avec le package Mysql, est assez rapide pour les bases de petites tailles et c’est à peu près tout! On peut l’employer aussi sur des serveurs de réplication, ou si vous pouvez vous permettre de suspendre les opérations d’écritures pendant un temps assez long
  • Un simple tar sur le répertoire de données, est plus rapide mais peut rester lent, surtout si vous effectuer une backup sur le réseau
  • Un simple tar, couplé à un volume manager supportant les snapshots, comme Veritas ou ZFS. La solution de sauvegarde Mysql qui vient à l’esprit est Linux Volume Manager (LVM), maintenant fourni en standard avec la plupart des distributions Linux. Cette option verrouille les tables quelques secondes seulement si la backup est effectuée sur un snapshot!

D’autres méthodes existent bien évidemment mais ne seront pas abordées ici.


Avant de Lancer la Sauvegarde

Tout ce dont vous avez besoin est d’avoir le répertoire de données Mysql hébergé sur une partition LVM. Ainsi que 10% d’espace libre sur son volume group pour créer le snapshot. Les paramètres sont similaires au client Mysql en ligne de commandes, c’est-à-dire les mêmes options à spécifier pour le user et le mot de passe pour une utilisation facile.

Le script se connecte au serveur Mysql local, met un lock en lecture. Il crée ensuite un snapshot de la partition LVM, et libère le verrou. Le répertoire de données est alors sauvegardé avec tar et copié vers le répertoire de destination de votre choix, avant que le snapshot ne soit détruit.
Il est préférable de l’exécuter sous le compte root. Si ce n’est pas possible (ou non désiré), vous pouvez utiliser sudo pour les commandes mount et lv. Assurez-vous que les fichiers Mysql soient accessibles en lecture.
Ce script vous permettra de faire une sauvegarde de vos bases Mysql en un clin d’oeil grâce aux snapshots LVM.


Script de Sauvegarde Mysql

#!/bin/bash

user=$LOGNAME
password=
datadir=
tmpmountpoint="/mnt"
dstdir="/tmp"

usage () {
  echo "Usage: $0 [OPTION]"
  echo "-d, --dest=name       Destination directory. Default is /tmp"
  echo "-h, --help            Display this help and exit."
  echo "-p, --password[=name] Password to use when connecting to server. If password is"
  echo "                      not given it's asked from the tty."
  echo "-t                    Temporary mount point for the snapshot. Default is /mnt."
  echo "-u, --user=name       User for login if not current user"
  exit 1
}

until [ -z "$1" ]; do
  case "$1" in
    -u)
      [ -z "$2" ] && usage
      user="$2"
      shift
      ;;
    --user=*)
      user=`echo $1|cut -f 2 -d '='`
      ;;
    -p*)
      password=`echo $1|sed -e s/"^-p"//g`
      ;;
    --password)
      echo -n "Enter password: "
      stty -echo
      read password
      stty echo
      ;;
    --password=*)
      password=`echo $1|cut -f 2 -d '='`
      ;;
    -d)
      [ -z "$2" ] && usage
      dstdir="$2"
      shift
      ;;
    --dest=*)
      dstdir=`echo $1|cut -f 2 -d '='`
      ;;
    -t)
      [ -z "$2" ] && usage
      tmpmountpoint="$2"
      shift
      ;;
    * )
    usage
    ;;
  esac
  shift
done

[ -z $password ] && echo "Empty password!" && usage
[ ! -d $dstdir ] && echo "$dstdir does not exist" && exit 1

# Check if temp mount point not used
[ `mount | grep "$tmpmountpoint" | wc -l` -ne 0 ] && exit 1

# Get Mysql data directory
datadir=`mysql -u $user -p$password -Ns -e "show global variables like 'datadir'"|cut -f 2|sed -e s/"\/$"//g`
[ -z "$datadir" ] && exit 1

# Get snap name and size
vg=`mount | grep $datadir | cut -d ' ' -f 1 | cut -d '/' -f 4 | cut -d '-' -f 1`
lv=`mount | grep $datadir | cut -d ' ' -f 1 | cut -d '/' -f 4 | cut -d '-' -f 2`
[ -z $lv ] && echo "Mysql data dir must be mounted on a LVM partition!" && exit 1
snap=$lv"snap"
snapsize=$(expr `df -m $datadir | tail -1 | tr -s ' ' | cut -d ' ' -f 2` / 10)M

# Backup
echo "Locking databases"
mysql -u$user -p$password << EOF
FLUSH TABLES WITH READ LOCK;
system lvcreate --snapshot -n $snap -L$snapsize /dev/$vg/$lv;
UNLOCK TABLES;
quit
EOF
echo "Databases unlocked"

echo "Backing up databases"
mount /dev/$vg/$snap $tmpmountpoint
cd $tmpmountpoint
tar cfz $dstdir/mysql.tar.gz *
cd
umount $tmpmountpoint
lvremove -f /dev/$vg/$snap
echo "Databases backed up in $dstdir"

exit 0

No responses yet

Comments RSS

Leave a Reply