lundi 18 août 2008

Sauvegardes MySQL avec LVM2

Les avantages du LVM2

La nouvelle mouture du LVM (Logical Volume Manager) qui a vu le jour le 20 février 2002 avec la première version stable apporte les améliorations suivantes :

  • compatible avec les noyaux 2.6.x
  • compatible avec le LVM1
  • mise à jour transactionnelle des metadata (permet une récupération plus rapide dans le cas d'un crash serveur)
  • supporte le clustering de fichiers (gfs, ocfs)
  • supporte l'extension des volumes strippés
  • supporte le mirroring des volumes
  • supporte beaucoup plus de volumes physiques et logiques (256 -> 232)
  • snapshots en lecture/écriture

Sauvegarde MySQL

Les 2 types de sauvegardes possibles vont être étudiées dans le cas où LVM2 est disponible, permettant une interruption de service des plus courtes surtout dans le cas de bases très sollicitées et/ou ayant une volumétrie importante.

Sauvegarde Physique

Pour effectuer une sauvegarde physique il faut que les données sur disque soient dans un état consistent, c'est à dire que les fichiers ne soient pas modifiés durant la sauvegarde. Pour cela, la méthode habituelle consiste à arrête le serveur de base de données et à sauvegarder les fichiers. Cependant, cela nécessite un arrêt de service, et plus les fichiers sont nombreux et de taille importante, plus la sauvegarde durera longtemps. Ceci n'est souvent pas applicable dans les services ayant une activité de 24/24 7j/7. L'utilisation du LVM2 satisfait donc pleinement à cette situation.

Cette étape se déroule en 8 temps :

  • vérouiller en lecture toutes les tables avec la commande FLUSH TABLES WITH READ LOCK
  • créer un snapshot
  • relever la position des binlogs au cas où il faudrait construire un slave à partir de cette sauvegarde
  • dévérouiller des tables
  • monter le volume logique correspondant au snapshot
  • copier les fichiers se trouvant dans le snapshot
  • démonter le volume logique
  • supprimer le snapshot

Passons à la pratique :

Voilà le volume logique que j'utilises pour stocker mes données MySQL :

 root@McQueen:~# lvscan |grep mysql
ACTIVE '/dev/vg01/lv_mysqldb' [1.00 GB] inherit

root@McQueen:~# mount|grep mysql
/dev/mapper/vg01-lv_mysqldb on /var/lib/mysql type ext3
(rw,noatime)

Commençer la procédure de sauvegarde en se connectant au serveur :

 mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status\G
*************************** 1. row ***************************
File: db10-bin.000005
Position: 1081
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

Garder la connexion précédente ouverte, car sinon le verrou global posé est libéré, et créer le snapshot qui sera utilisé pour la sauvegarde :

root@McQueen:~# lvcreate --snapshot --name mysql_datadir_snapshot
-L 200M /dev/vg01/lv_mysqldb
Logical volume "mysql_datadir_snapshot" created

Vous avez remarqué que je n'utilise pas la même taille pour mon snapshot (200Mo) que pour la base (1Go). En effet, la taille allouée au snapshot ne sera utilisée que pour les nouvelles écritures et pour les héberger les blocs modifiés sur le volume logique source (pour plus d'information voir http://www.tldp.org/HOWTO/LVM-HOWTO/snapshotintro.html)

Vous pouvez ensuite libérer le verrou acquis en vous déconnectant du serveur MySQL ou en utilisant la commande UNLOCK TABLES

Monter le volume logique correspondant au snapshot créé pour effectuer la sauvegarde physique des fichiers

 mount /dev/vg01/mysql_datadir_snapshot /mnt

Sauvegarder les fichiers MySQL

 tar cvzf mysqlbackup.tgz /mnt /etc/mysql

Démonter le snapshot et le supprimer

 umount /mnt && lvremove -f /dev/vg01/mysql_datadir_snapshot

Sauvegarde Logique

Pour effectuer une sauvegarde logique il faut que le serveur de bases de données soit démarré et acquérir un verrou global à chaque base pour sauvegarder les tables sans qu'elles soient désynchronisées. Selon l'activité de la base et sa volumétrie, l'impact sur les traitements courants et la durée de la sauvegarde peuvent être importants.

Cette étape se déroule en 9 temps :

  • vérouiller en lecture de toutes les tables avec la commande FLUSH TABLES WITH READ LOCK
  • créer du snapshot
  • dévérouiller les tables / se déconnecter
  • monter le volume logique correspondant au snapshot
  • démarrer un second serveur avec les fichiers se trouvant dans le snapshot
  • effectuer la sauvegarde logique
  • arrêter le second serveur de base de données
  • démonter le volume logique
  • supprimer le snapshot

Passons à la pratique :

Voilà le volume logique que j'utilises pour stocker mes données MySQL :

 root@McQueen:~# lvscan |grep mysql
ACTIVE '/dev/vg01/lv_mysqldb' [1.00 GB] inherit

root@McQueen:~# mount|grep mysql
/dev/mapper/vg01-lv_mysqldb on /var/lib/mysql type ext3
(rw,noatime)


Commençer la procédure de sauvegarde en se connectant au serveur :

 mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)

Garder la connexion précédente ouverte, car sinon le verrou global posé est libéré, et créer le snapshot qui sera utilisé pour la sauvegarde :

root@McQueen:~# lvcreate --snapshot --name mysql_datadir_snapshot
-L 200M /dev/vg01/lv_mysqldb
Logical volume "mysql_datadir_snapshot" created

Vous pouvez ensuite libérer le verrou acquis en vous déconnectant du serveur MySQL ou en utilisant la commande UNLOCK TABLES

Monter le volume logique correspondant au snapshot créé

 mount /dev/vg01/mysql_datadir_snapshot /mnt

Démarrer un second serveur de base de données à partir des fichiers du snapshot, en prenant soin de désactiver le réseau puisque l'on se connectera directement en utilisant la nouvelle socket

 mysqld --basedir=/usr --datadir=/mnt --user=mysql --skip-networking
--socket=/mnt/mysqld.sock

Exporter les données

 mysqldump -S /mnt/mysqld.sock -B base1 base2

Il est aussi possible d'utiliser l'option --master-data pour exporter la position du serveur au niveau des fichiers de log binaires pour mettre en place une réplication

Arrêter le second serveur de base de données

 mysqladmin --defaults-file=/etc/mysql/debian.cnf
-S /mnt/mysqld.sock shutdown

Démonter le snapshot et le supprimer

 umount /mnt && lvremove -f /dev/vg01/mysql_datadir_snapshot

Conclusion

Cet article permet de comprendre l'intérêt d'utiliser le LVM2 pour effectuer ses sauvegardes MySQL et éviter d'avoir à interrompre le service utilisant le serveur de base de données. Il faudra cependant considérer l'impact sur les performances que peut induire l'existence d'un snapshot. En effet, les données modifiées sur le volume logique source sont déplacées vers le snapshot ce qui a un coup supplémentaire. Si votre serveur n'est pas déjà submergé d'activité i/o vous n'avez pas à vous inquiéter, dans le cas contraire rabattez vous sur un esclave ou tout autre machine moins sollicitée ou disposant d'une bande passante i/o plus importante.