Blog

Blog

Faire une sauvegarde avec pgBackRest

Comme je l'ai expliqué dans mes articles, on peut utiliser pgbasebackup pout faire les sauvegardes et on peut faire du PITR à la main, cependant, on peut aussi chercher des outils un peu plus évolués pour se faciliter la tâche.
J'ai testé pgBackRest.
Bon d'accord, "l'emballage" de l'outil n'est pas sexy... On pourrait lui reprocher un site propre mais pas très attrayant. Ça manque de marketing. Mais quand on a passé cette barrière, on se rend compte que l'outil est assez facile à prendre en main et rend de beaux services.

Installation

Il n'existe pas de package (Linux) ni d'installeur (Windows) pour pgBackRest. L'outil est écrit en perl. C'est un "plus" pour moi, un "moins" pour beaucoup d'autres et un point neutre pour la grande majorité.
La procédure est très bien indiquée dans la documentation utilisateur http://www.pgbackrest.org/user-guide.html#installation.
Pour les users Windows, je pense que ça doit marcher, il faudra juste installer un émulateur comme cygwin ou celui fourni avec Windows 10.

Configuration

Oui, on trépigne d'impatience, mais avant de pouvoir lancer une sauvegarde, il va falloir configurer la bête.

Stanza ou Stance

Tout d'abord, un peu de vocabulaire. PgBackRest appelle "Stanza" la configuration d'un groupe de bases de données (database cluster) à sauvegarder, qu'on pourrait traduire par stance qui signifie, en poésie, "un nombre défini de vers comprenant un sens parfait et arrangé d’une manière particulière qui s’observe dans tout le poème" (source Wikipedia).
Une stance comporte tous les paramètres de sauvegarde d'un cluster de bases de données.

Création/paramétrage du stockage

Le répertoire de stockage doit avoir pour user postgres:postgres avec des droits 750. Pour la suite ce répertoire s'appellera /mon/repertoire/de/stockage/de/backup.

Configuration d'une stance

Le fichier de configuration de stance est /etc/pgbackrest.conf. Le user postgres doit avoir les droits de lecture sur le fichier.

Il doit comporter une section [global] valable pour toutes les stances et une section par stance avec le nom du cluster entre crochets en début de section.
La section [global] doit comporter le chemin vers le répertoire de sauvegarde et éventuellement la stratégie de rétention des sauvegardes.
Le tutoriel propose de mettre une rétention à 2 backups full.

Voilà la tête de mon fichier de configuration:
[global]
repo-path=/mon/repertoire/de/stockage/de/backup
retention-full=2

[main]
db-path=/var/lib/postgresql/9.6/main

Création d'une stance

Il faut ensuite dire à pgBackRest qu'il y a une nouvelle stance. L'option
sudo -u postgres pgbackrest --stanza=main --log-level-console=info stanza-create 
2017-02-17 14:28:08.486 P00   INFO: stanza-create command begin 1.15: --db-path=/var/lib/postgresql/9.6/main --log-level-console=info --repo-path=/var/lib/pgbackrest --stanza=main
2017-02-17 14:28:08.872 P00   INFO: stanza-create command end: completed successfully

Configurer l'archivage

Il faut configurer l'archivage des WAL avec pgBackRest et un niveau de détail suffisant dans les WAL pour pouvoir faire du PITR.
Voici les paramètres à modifier:
archive_command = 'pgbackrest --stanza=main archive-push %p'
archive_mode = on
listen_addresses = '*'
log_line_prefix = ''
max_wal_senders = 3
wal_level = logical
J'avais déjà configuré mon wal_level à logical. La documentation de pgBackRest recommande d'augmenter max_wal_level pour pouvoir par la suite ajouter une standby sans redémarrer le maître...Sous PostgreSQL 10, la valeur par défaut devrait être 10.
Un redémarrage est nécessaire après la modification de ces paramètres.

Vérification

Une petite vérification que tout est OK:
sudo -u postgres pgbackrest --stanza=main --log-level-console=info check
2017-02-19 22:21:14.472 P00   INFO: check command begin 1.15: --db-path=/var/lib/postgresql/9.6/main --log-level-console=info --repo-path=/var/lib/pgbackrest --stanza=main
2017-02-19 22:21:15.678 P00   INFO: WAL segment 000000060000000000000055 successfully stored in the archive at '/var/lib/pgbackrest/archive/main/9.6-1/0000000600000000/000000060000000000000055-4c059aaad9851886721312972a427d0e72c3543d.gz'
2017-02-19 22:21:15.680 P00   INFO: check command end: completed successfully

 Sauvegarder

Ça y est, on va pouvoir faire une sauvegarde.

Sauvegarde complète

Par défaut, pgBackRest fait une sauvegarde complète. Il suffit de lancer la commande avec l'option backup :
sudo -u postgres pgbackrest --stanza=main --log-level-console=info backup
2017-02-19 22:23:35.793 P00   INFO: backup command begin 1.15: --db-path=/var/lib/postgresql/9.6/main --log-level-console=info --repo-path=/var/lib/pgbackrest --retention-full=2 --stanza=main
2017-02-19 22:23:36.005 P00   INFO: last backup label = 20170217-145055F_20170219-221932I, version = 1.15
2017-02-19 22:23:36.717 P00   INFO: execute non-exclusive pg_start_backup() with label "pgBackRest backup started at 2017-02-19 22:23:35": backup begins after the next regular checkpoint completes
2017-02-19 22:23:37.018 P00   INFO: backup start archive = 000000060000000000000057, lsn = 0/57000028
2017-02-19 22:23:38.510 P01   INFO: backup file /var/lib/postgresql/9.6/main/global/pg_control (8KB, 99%) checksum 4b8c6eb02288dcf371d1db9e5811e4540b298692
2017-02-19 22:23:38.517 P01   INFO: backup file /var/lib/postgresql/9.6/main/pg_logical/replorigin_checkpoint (8B, 100%) checksum 347fc8f2df71bd4436e38bd1516ccd7ea0d46532
2017-02-19 22:23:38.538 P00   INFO: incr backup size = 8KB
2017-02-19 22:23:38.538 P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
2017-02-19 22:23:39.642 P00   INFO: backup stop archive = 000000060000000000000057, lsn = 0/57000130
2017-02-19 22:23:39.809 P00   INFO: new backup label = 20170217-145055F_20170219-222339I
2017-02-19 22:23:39.839 P00   INFO: backup command end: completed successfully
2017-02-19 22:23:39.840 P00   INFO: expire command begin 1.15: --log-level-console=info --repo-path=/var/lib/pgbackrest --retention-archive=2 --retention-full=2 --stanza=main
2017-02-19 22:23:39.854 P00   INFO: full backup total < 2 - using oldest full backup for archive retention
2017-02-19 22:23:39.855 P00   INFO: expire command end: completed successfully
On voit qu'en fin de sauvegarde, il vérifie l'âge des sauvegardes et la durée de rétention pour savoir si des backups sont expirés.

 Sauvegarde différentielle

Pour faire une sauvegarde différentielle, il suffit d'ajouter l'option --type=diff:
sudo -u postgres pgbackrest --stanza=main --log-level-console=info --type=diff backup
2017-02-19 22:25:42.572 P00   INFO: backup command begin 1.15: --db-path=/var/lib/postgresql/9.6/main --log-level-console=info --repo-path=/var/lib/pgbackrest --retention-full=2 --stanza=main --type=diff
2017-02-19 22:25:42.757 P00   INFO: last backup label = 20170217-145055F, version = 1.15
2017-02-19 22:25:43.471 P00   INFO: execute non-exclusive pg_start_backup() with label "pgBackRest backup started at 2017-02-19 22:25:42": backup begins after the next regular checkpoint completes
2017-02-19 22:25:43.672 P00   INFO: backup start archive = 000000060000000000000059, lsn = 0/59000028
2017-02-19 22:25:44.522 P01   INFO: backup file /var/lib/postgresql/9.6/main/base/12449/pg_internal.init (110KB, 69%) checksum 03674f79eeaded1a0a69dbd044e5b40c5728726b
2017-02-19 22:25:44.526 P01   INFO: backup file /var/lib/postgresql/9.6/main/global/pg_internal.init (16.2KB, 79%) checksum a1d214a73f88d430b87d13ee6bc674d7e97f7da7
2017-02-19 22:25:44.530 P01   INFO: backup file /var/lib/postgresql/9.6/main/pg_notify/0000 (8KB, 84%) checksum 0631457264ff7f8d5fb1edc2c0211992a67c73e6
2017-02-19 22:25:44.537 P01   INFO: backup file /var/lib/postgresql/9.6/main/pg_multixact/offsets/0000 (8KB, 89%) checksum 0631457264ff7f8d5fb1edc2c0211992a67c73e6
2017-02-19 22:25:44.543 P01   INFO: backup file /var/lib/postgresql/9.6/main/pg_clog/0000 (8KB, 94%) checksum b075d6fc4b4ae9e4a0576a187b0f59d1f13fc457
2017-02-19 22:25:44.546 P01   INFO: backup file /var/lib/postgresql/9.6/main/global/pg_control (8KB, 99%) checksum f577e11ae0d7fb912bb1167f6a21815fd32ddab6
2017-02-19 22:25:44.550 P01   INFO: backup file /var/lib/postgresql/9.6/main/pg_logical/replorigin_checkpoint (8B, 100%) checksum 347fc8f2df71bd4436e38bd1516ccd7ea0d46532
2017-02-19 22:25:44.569 P00   INFO: diff backup size = 158.3KB
2017-02-19 22:25:44.569 P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
2017-02-19 22:25:45.673 P00   INFO: backup stop archive = 000000060000000000000059, lsn = 0/590000F8
2017-02-19 22:25:45.842 P00   INFO: new backup label = 20170217-145055F_20170219-222545D
2017-02-19 22:25:45.877 P00   INFO: backup command end: completed successfully
2017-02-19 22:25:45.878 P00   INFO: expire command begin 1.15: --log-level-console=info --repo-path=/var/lib/pgbackrest --retention-archive=2 --retention-full=2 --stanza=main
2017-02-19 22:25:45.891 P00   INFO: full backup total < 2 - using oldest full backup for archive retention
2017-02-19 22:25:45.892 P00   INFO: expire command end: completed successfully

 Pour en savoir plus

Vous trouverez toutes les documentations sur http://www.pgbackrest.org.
Voici une liste de liens spécifiques: