La mise en place de backups est une étape cruciale et incontournable en tant que pocesseur d’un serveur dédié. Vous devez pouvoir repartir le plus vite possible en cas de crash disque, avec des pertes de données réduites au minimum.
Pour MySQL, il existe deux possibilités:
- la mise en place d’un deuxième serveur, en réplication maître/esclave; le serveur esclave se synchronisant à intervalles réguliers sur le serveur maître;
- la réalisation périodique de dumps des bases et leur transfert en lieu sûr.
C’est la deuxième solution que nous allons explorer aujourd’hui, en réalisant un script bash dont le but est de réaliser un dump par base existante, en sachant que cette liste peut bien évidemment évoluer de jour en jour; le script devra donc gérer cet aspect du problème. Une fois le script réalisé, il vous sera alors possible de l’intégrer à votre crontab afin d’automatiser son exécution. Nous nous limiterons dans cet article à la réalisation du dump en lui-même, le transfert des données en lieu sûr dépend des possibilités qui vous sont offertes. Il est possible de réaliser un transfert via scp vers un autre serveur, d’uploader les données par FTP, de les envoyer à une adresse e-mail, …
Les bases de données sont stockées dans le répertoire /var/lib/mysql, chaque base étant contenue dans un répertoire portant son nom. Pour obtenir la liste des bases de données, il suffit donc de faire un ls de ce répertoire et de vérifier que l’entrée retournée est un répertoire. Ensuite, à l’aide de la commande mysqldump et d’un user spécialement créé pour le backup, nous réaliserons un fichier compressé pour chaque base de données. L’utilisateur créé pour le backup aura des privilèges communs à toutes les bases : le select, forcément, mais aussi la possibilité de verrouiller les tables pendant leur sauvegarde, on s’assure ainsi que les données backupées seront cohérentes.
Mais, me diriez-vous, pourquoi ne pas directement sauvegarder les fichiers présents dans /var/lib/mysql ? Tout simplement parce qu’un seul octect corrompu lors du transfert ou de la copie rendrait le backup totalement inutilisable. Un dump réalisé par la commande mysqldump contient l’ensemble des requêtes permettant de recréer la base du début, c’est à dire les requêtes « create table » et « insert », qu’il suffit de rejouer en cas de besoin.
La première étape est de créer l’utilisateur dédié au backup, que nous appelerons tout simplement « backup ». Original, non ? Vous pouvez faire cela via PhpMyAdmin, ou directement en console en entrant les requêtes suivantes après que vous vous soyez connecté en root au serveur MySQL:
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'mot de passe de votre choix';
REVOKE ALL PRIVILEGES ON *.* FROM 'backup'@'localhost';
REVOKE GRANT OPTION ON *.* FROM 'backup'@'localhost';
GRANT SELECT, LOCK TABLES ON *.*
TO 'backup'@'localhost'
WITH
MAX_QUERIES_PER_HOUR 0
MAX_CONNECTIONS_PER_HOUR 0
MAX_UPDATES_PER_HOUR 0
MAX_USER_CONNECTIONS 0 ;
N’oubliez pas de mettre un mot de passe particulièrement robuste; en effet cet user a un privilège global de selection sur toutes les bases de données. Vous pouvez par exemple utiliser mon générateur de mots de passe.
Ensuite, avec votre éditeur de texte préféré, créez un fichier que vous nommerez par exemple backup.sh et mettez-y le contenu suivant:
#!/bin/sh
backup=/home/backup
sqlusr="backup"
sqlpwd="password"
sqlhost="localhost"
date=`date +%Y-%m-%d`
for db in `ls /var/lib/mysql`; do
if [ -d /var/lib/mysql/$db ]; then
if [ ! -e $backup/$date-db-$db.tar.bz2 ]; then
nice mysqldump --host=$sqlhost --user=$sqlusr --password=$sqlpwd \
--quote-names --extended-insert --skip-disable-keys --quick $db \
> $backup/$date-db-$db.sql
nice tar cjf $backup/$date-db-$db.tar.bz2 $backup/$date-db-$db.sql
rm backup/$date-db-$db.sql
fi
fi
done
La variable backup est le répertoire cible où seront créés les fichiers .tar.bz2; ce répertoire doit permettre l’écriture et la lecture à l’utilisateur qui réalise le backup, les autres utilisateurs du système ne devraient y avoir aucun accès. N’oubliez pas de renseigner le mot de passe de l’utilisateur backup. Pour l’explication des différentes options apportées à la commande mysqldump, lisez la page de manuel correspondante. La commande nice mise en début de ligne permet de limiter la priorité du processus de backup, afin de ne pas surcharger votre machine par un script gourmant. Notez aussi que durant le backup, les tables sont lockées une à une, ce qui pourrait affecter le fonctionnement des sites en dépendant; faites donc cette opération pendant la nuit…
Autre chose très importante: ce fichier ne devrait pas être lisible par les autres utilisateurs, sinon ils seraient en possession du mot de passe de l’utilisateur backup. Mettez donc le fichier en chmod 700; ce qui le rend au passage exécutable.
Un fichier sera donc généré pour chaque base, sous la forme AAA-MM-JJ-nomDeLaBase.tar.bz2. Il ne vous reste plus qu’à le transférer dans un lieu sûr, et à importer le dump dans votre serveur MySQL en cas de crash.
Si vous ne désirez sauvegarder qu’une liste de bases présices, mettez leur nom (un par ligne) dans un fichier texte, par exemple /root/dblist. Remplacez dans le script la ligne
for db in `ls /var/lib/mysql`; do
par
for db in `cat /root/dblist`; do
Ceci peut par exemple être utilisé pour réaliser un backup plus régulier de certaines bases précises tout en laissant le backup de toutes les bases existantes à une fréquence moins importante.
MySQL backup, dump