rsync : sauvegarder des bases MySQL à chaud

14/06/2006 20:54:34

Dans l’administration d’un serveur de base de données relationnelles, chacun se heurte à un douloureux problème, celui de la sauvegarde.

En effet, il existe pas mal de solutions pour assurer la nécéssaire sauvegarde des bases de données sur un serveur en production, mais peu sont réellement satisfaisantes. On peut les classer dans deux catégories :

  • La mentalité du « uptime à tout prix » : on veut bien faire des sauvegardes, mais surtout, ne pas arrêter le serveur. Cela nécéssite d’effectuer un verrouillage de type LOCK TABLES READ sur l’ensemble des tables pendant toute la durée de la sauvegarde, ce qui restreint énormément les outils utilisables :
    • mysqldump : le plus propre car il génère du SQL à placer dans un fichier, mais aussi le moins « commode » car tout est concentré dans un fichier (et les fichiers de 10 go n’ont jamais été très pratiques à manipuler), qui est en général plus lourd que l’équivalent stocké en « interne ». Alors oui, bzip2, tout ça… bien sûr, c’est vraiment très pratique de balancer un bzip2 sur un fichier de 15 go ce qui va immanquablement saturer toutes les ressources de la machine pendant un certain nombre d’heures chaque nuit. L’autre solution consiste à envoyer la sortie sur un client quelconque qui envoie le tout sur une autre machine, qui va se faire une joie de saturer votre connexion et garder toutes vos tables verrouillées pendant un temps très appréciable pour les utilisateurs de votre site web / application. Evidemment, il ne sait pas ce qui signifie le mot « différenciel » : ici, c’est tout ou rien.
    • mysqlhotcopy : il verrouille toutes les tables et recopie les fichiers internes quelque part, ce qui est déjà nettement plus appréciable au niveau des ressources système. Il peut aussi transférer les fichiers par scp, mais il est aussi sourd que mysqldump au mot « différenciel ». Certains objecteront que, dans le cas d’une sauvegarde à distance où la bande passante est comptée (i.e. Internet) on peut très bien placer la sauvegarde dans un dossier local, puis faire un rsync (utilitaire de sauvegarde différencielle) sur ce dossier. Dans ce cas, j’espère que vous ne serez pas trop gêné de ne pouvoir utiliser le disque dur de votre serveur qu’à moitié, puisqu’il faut un espace de stockage total d’au minimum le double de la taille de la base de données pour pouvoir mettre en oeuvre cette solution. De plus, ça fait souffrir les I/O (lecture/écriture sur disque) pour rien.
  • La mentalité du « rien à foutre, je tiens à ma liberté » : ce sont ceux qui revendiquent le droit d’être libre dans le choix de leur utilitaire de sauvegarde, quitte à devoir arrêter leur serveur MySQL pour effectuer cette sauvegarde. Ils ont en général utilisé une des deux solutions de la précédente catégorie pendant longtemps, jusqu’à ce qu’il se soient rendus compte avec horreur de la lourdeur et la rigidité navrante de ces outils dès lors que leur base de données dépasse quelques centaines de mégaoctets. Ils peuvent alors utiliser rsync pour effectuer une sauvegarde différentielle. Mais le serveur MySQL restera down pendant tout le temps de la sauvegarde, ce qui peut s’avérer innaceptable dans nombre de situations (notamment quand un certain nombre d’applications utilisent le serveur).

Comparons les avantages des deux catégories : l’une permet de laisser le serveur MySQL disponible pendant l’opération, l’autre autorise les sauvegardes différentielles.

Que diriez-vous de combiner ces avantages ?

C’est ce que votre serviteur a fait : j’ai développé un script PHP qui suit le principe de mysqlhotcopy en l’associant à rsync. Vous pouvez, grâce à ce script, faire des sauvegardes différentielles de bases de données MySQL sans briser l’uptime du serveur, en local ou à distance, en clair (rsh) ou en crypté (ssh).

Toutes les informations sur l’installation et le fonctionnement du script se trouve dans les commentaires de ce dernier.

Rédigé par e-t172 |

10 réponses to “rsync : sauvegarder des bases MySQL à chaud”

  1. Plor a répondu le 15/06/2006 à 12:11 #

    Bon script, utile
    Il nécessite néanmoins PHP5, je pense qu’il est possible de faire une version compatible PHP4 en changeant certaines choses, mais en perdant en performances au passage…

  2. e-t172 a répondu le 15/06/2006 à 13:11 #

    Le problème avec PHP4 est qu’il ne supporte pas la fonction stream_select() utilisée pour faire la passerelle entre les flux std* (voir le code).

    Alors oui, il est possible de faire une version compatible mais le code sera beaucoup plus sale et probablement moins performant.

    Mais d’un autre côté, je ne vois pas l’intérêt d’assurer cette compatibilité puisqu’ici on parle de gens qui ont vraisemblablement le contrôle sur l’installation PHP de leur serveur et qui peuvent donc compiler un binaire PHP5 séparé de celui de PHP4 (par exemple dans /usr/local/php5).

  3. keger a répondu le 15/06/2006 à 20:43 #

    Ca sera de l’aspirine pour moi monsieur s’il vous plait.

  4. radiateur a répondu le 26/11/2006 à 21:48 #

    Bonjour,

    Je n’arrive pas à m’en servir:

    $ ./mysql-rsync.php — –archive /srv/mysql www.dest.com:/srv/backups

    Par quoi je dois remplacer /srv/mysql ? Est-ce que le script n’écrit pas le flush sur stdout ?

  5. e-t172 a répondu le 26/11/2006 à 22:50 #

    Garde la ligne de commande telle qu’elle est, modifie le script pour configurer l’accès à MySQL si ce n’est pas déjà fait, et tout ira pour le mieux.

  6. radiateur a répondu le 27/11/2006 à 15:07 #

    La connexion à mysql se passe bien mais lorsque j’invoque la commande:

    rsync-mysql.php — –archive /srv/mysql radiateur@localhost:/srv/backups

    J’ai:

    rsync: link_stat "/srv/mysql" failed: No such file or directory (2)
    rsync error: some files could not be transferred (code 23) at main.c(791)

  7. e-t172 a répondu le 27/11/2006 à 18:28 #

    Ca signifie simplement que tu t’es trompé dans le chemin du répertoire de données de MySQL, lequel n’est manifestement pas /srv/mysql.

  8. davido a répondu le 09/03/2008 à 15:47 #

    Le lien est brisé :(
    Dommage ce script a l’air vraiment très intéressant et correspond à ce que je voudrais faire pour sauvegarder la base Mysql de mon serveur !

  9. e-t172 a répondu le 09/03/2008 à 16:14 #

    Corrigé.

  10. Ad71 a répondu le 24/03/2008 à 21:42 #

    bonjour,
    Un grand merci pour ce travail, je compte l’utiliser d’ici quelques jours sur un vps de Gandi avec peu de ressources. J’espère que ça marche.

URL de trackback |