Archivage continu Postgresql avec WAL-E
La sauvegarde de sa base de données est une chose essentielle pour la pérennité de son site. Actuellement je fonctionne sur le principe très basique du dump (pg_dump) de toute ma base de données. Mais cette pratique est loin d’être optimum, et il faut effectuer des dumps assez régulièrement s’il l’on ne veut pas perdre trop de données en cas de crash.
Pour la sauvegarde, il existe un autre moyen avec Postgresql, qui consiste dans un premier temps à enregistrer une sauvegarde complète de la base, et ensuite de ne sauvegarder que les changements apportés à la base sous forme de fichiers WAL. Ainsi « terminé » les gros backups entiers de la base de données, et nous pouvons garder une trace de chaque action effectuée sur la base de données et les rejouer à n’importe quel moment (Point-In-Time Recovery).
Faire des sauvegardes c’est bien, mais faut aussi les sauvegarder quelque part ailleurs que sur le serveur. Sinon en cas de problème avec le disque dur, bye bye la BDD et bye bye les sauvegardes. Et pour cela il existe un très bon outil: Amazon S3. Je ne vais pas détailler ici comment utiliser S3, mais c’est vraiment simple.
Du coup, maintenant nous avons un outil pour effectuer un archivage continu de la base de données, et un outil pour le stockage.
Et il n’existerais pas un outil pour simplifier l’utilisation de ces choses ? Et bien si: WAL-E, à ne pas confondre avec Wall-E
Toute la suite de l’installation se fait sur une Ubuntu 12.04.2 LTS avec Postgresql 9.1.
Installation de WAL-E
On commence avec l’installation des dépendances:
aptitude install lzop pv python-gevent
Téléchargement de WAL-E. Pour moi c’est la version 0.6:
wget https://github.com/wal-e/wal-e/archive/v0.6.zip
Et installation:
unzip v0.6.zip setup.py build setup.py install
Installation de Daemontools
Afin d’exécuter WAL-E dans un environnement sécurisé, nous avons besoin de envdir présent dans la suite Deamontools de D.J. Bernstein.
Préparation:
mkdir -p /package chmod 1755 /package cd /package
Téléchargement:
wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
Décompression:
gunzip daemontools-0.76.tar tar -xpf daemontools-0.76.tar cd admin/daemontools-0.76
Attention, il est nécessaire de modifier un fichier de configuration afin de pouvoir compiler les daemontools sur Ubuntu.
Modifiez le fichier /package/admin/daemontools/src/conf-cc et ajouter « -include /usr/include/errno.h » à la fin de la première ligne (commande gcc):
gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -include /usr/include/errno.h
Nous pouvons maintenant compiler:
package/install
Configuration de WAL-E
Dans un premier temps, nous allons préparer les variables d’environnement nécessaires à l’utilisation de WAL-E. Ces variables sont les informations de connexion à votre S3.
Pour retrouver access-key et secret-key-content, allez ici et connectez-vous.
mkdir -p /etc/wal-e.d/env echo "secret-key-content" > /etc/wal-e.d/env/AWS_SECRET_ACCESS_KEY echo "access-key" > /etc/wal-e.d/env/AWS_ACCESS_KEY_ID echo 's3://some-bucket/directory/or/whatever' > /etc/wal-e.d/env/WALE_S3_PREFIX chown -R root:postgres /etc/wal-e.d chmod 760 /etc/wal-e.d/env/*
Nous allons maintenant modifier le fichier /etc/postgresql/9.1/main/postgresql.conf avec les informations suivantes:
wal_level = archive archive_mode = on archive_command = 'envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-push %p' archive_timeout = 60
J’utilise le chemin entier pour appeler wal-e car sinon la commande ne fonctionne pas.
Il faut maintenant recharger Postgresql afin que la nouvelle configuration soit prise en compte:
/etc/init.d/postgresql reload
Et voila la configuration est terminée !
Sauvegarde complète de la base
Maintenant il est nécessaire de faire un premier backup de votre base de données vers S3, et donc d’exécuter votre première commande WAL-E à partir de l’environnement sécurisé grâce à envdir.
sudo -u postgres bash -c "envdir /etc/wal-e.d/env wal-e --s3-prefix=s3://some-bucket/directory/or/whatever backup-push /var/lib/postgresql/9.1/main/"
Cela peut prendre quelques secondes à quelques dizaines de minutes en fonction de la taille de votre base de données et de la vitesse d’upload entre votre serveur et Amazon.
A la fin de cette commande, vous devriez trouver 2 nouveaux dossiers dans votre bucket S3. Un dossier pour les backups de base et un dossier pour tous les fichiers WAL.
De nouveaux fichiers WAL sont envoyés très régulièrement vers votre s3.
Restauration des données
Pour récupérer sa base après un crash, il suffit de créer un fichier recovery.conf, qui sera lu au démarrage de Postgresql. Se fichier se place dans /var/lib/postgresql/9.1/main/.
restore_command = 'envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-fetch "%f" "%p"' recovery_target_time = '2013-06-18 20:00:00'
Il est possible de définir dans ce fichier une heure de restauration. Ainsi nous pouvons récupérer l’état de la base à moment bien précis. Si cette variable n’est pas définie, WAL-E essaie de restaurer l’état de la base au plus proche du dernier état.
Vérifier que le fichier recovery.conf appartient bien à postgresql. Sinon:
chown postgres: /var/lib/postgresql/9.1/main/recovery.conf
Maintenant il suffit de démarrer Postgresql
/etc/init.d/postgresql start
Vous pouvez suivre l’évolution du démarrage à partir des logs:
tail -f /var/log/postgresql/postgresql-9.1-main.log
Une fois la restauration terminée, le fichier recovery.conf devient recovery.done afin d’éviter tout problème en cas de redémarrage du serveur.
Et voilà, votre base a été restaurée.
Créer une nouvelle base de données à partir des sauvegardes
Par exemple pour une machine de développement, il peut être nécessaire de recréer une machine avec une base de données.
Dans un premier temps, il faut bêtement installer Postgresql.
Ensuite supprimer toutes les données présentes dans cette base:
/etc/init.d/postgresql stop rm -fr /var/lib/postgresql/9.1/main/*
On récupère la dernière version de base avec WAL-E:
sudo -u postgres bash -c "envdir /etc/wal-e.d/env wal-e --s3-prefix=s3://some-bucket/directory/or/whatever backup-fetch /var/lib/postgresql/9.1/main LATEST"
Une fois cela terminé, il suffit de reprendre toute la partie Restauration des données, juste au dessus, afin de récupérer la dernière version de la base.
Sauvegarde de base quotidienne
Il est peut être bien d’effectuer une sauvegarde totale de la base tous les jours, afin d’accélérer les remises en production en cas de crash. Ajoutez cette ligne à cron:
0 4 * * * sudo -u postgres bash -c "envdir /etc/wal-e.d/env /usr/local/bin/wal-e --s3-prefix=s3://backup.globewhere.com/database backup-push /var/lib/postgresql/9.1/main/"
Sources:
http://jamesreubenknowles.com/centos5-daemontools-143
https://github.com/wal-e/wal-e
https://gist.github.com/ruckus/2293434