Restauration, PITR avec pgBackRest

      Pour ce scénario, nous allons supposer que nous disposons d'une sauvegarde pgBackRest 2.x dans un environnement PostgreSQL 11 sur Debian 10 et que nous voulons effectuer un PITR au 23/07/2019 16h00min00s :

-- utilisateur postgres, une activite existe dans une table temoin avec une ligne inseree par seconde psql -p 5432 \set AUTOCOMMIT on create table temoin(col timestamp primary key); CREATE TABLE insert into temoin values(clock_timestamp()); INSERT 0 1 \watch 1 -- utilisateur root pg_ctlcluster 11 apptra001 stop rm -fr /var/lib/postgresql/11/apptra001/* -- utilisateur postgres, de quelles sauvegardes disposons-nous ? pgbackrest info stanza: apptra001 status: ok cipher: none db (current) wal archive min/max (11-1): 00000002000000000000000B/000000020000000000000010 full backup: 20190723-155522F timestamp start/stop: 2019-07-23 15:55:22 / 2019-07-23 15:55:34 wal start/stop: 00000002000000000000000B / 00000002000000000000000B database size: 23MB, backup size: 23MB repository size: 3.1MB, repository backup size: 3.1MB full backup: 20190723-163422F timestamp start/stop: 2019-07-23 16:34:22 / 2019-07-23 16:34:32 wal start/stop: 000000020000000000000010 / 000000020000000000000010 database size: 23.2MB, backup size: 23.2MB repository size: 3.2MB, repository backup size: 3.2MB -- utilisateur postgres, restore depuis la sauvegarde la plus recente anterieure au point de recover souhaite (note : si le cluster d'origine n'est pas supprime, il est possible d'utiliser --delta, ce qui est tres interessant sur les clusters volumineux) pgbackrest --set=20190723-155522F --log-level-console=info --stanza=apptra001 --type=time "--target=2019-07-23 16:00:00" restore ... -- utilisateur postgres, on regarde le contenu de recovery.conf cat /var/lib/postgresql/11/apptra001/recovery.conf restore_command = 'pgbackrest --log-level-console=info --stanza=apptra001 archive-get %f "%p"' recovery_target_time = '2019-07-23 16:00:00' -- utilisateur root, on redemarre le cluster pg_ctlcluster 11 apptra001 start -- utilisateur postgres, on regarde le fichier de log du cluster et on interroge la table temoin tail -50 /var/log/postgresql/postgresql-11-apptra001.log ... 2019-07-23 16:50:14.614 P00 INFO: archive-get command begin 2.10: [00000002000000000000000C, pg_wal/RECOVERYXLOG] --log-level-console=info --pg1-path=/var/lib/postgresql/11/apptra001 --repo1-path=/var/lib/pgbackrest --stanza=apptra001 2019-07-23 16:50:14.699 P00 INFO: found 00000002000000000000000C in the archive 2019-07-23 16:50:14.699 P00 INFO: archive-get command end: completed successfully (86ms) 2019-07-23 16:50:14.700 CEST [13648] LOG: restauration du journal de transactions « 00000002000000000000000C » à partir de l'archive 2019-07-23 16:50:14.749 CEST [13648] LOG: arrêt de la restauration avant validation de la transaction 921, 2019-07-23 16:00:00.332629+02 2019-07-23 16:50:14.749 CEST [13648] LOG: restauration en pause 2019-07-23 16:50:14.749 CEST [13648] ASTUCE : Exécuter pg_wal_replay_resume() pour continuer. psql -p 5432 select max(col) from temoin; max ---------------------------- 2019-07-23 15:59:59.330224 (1 ligne) -- utilisateur postgres, tout est OK, les operations de recover sont terminees select pg_wal_replay_resume(); pg_wal_replay_resume ---------------------- (1 ligne) tail -50 /var/log/postgresql/postgresql-11-apptra001.log ... 2019-07-23 16:55:42.109 CEST [13648] LOG: identifiant d'un timeline nouvellement sélectionné : 3 2019-07-23 16:55:42.240 CEST [13648] LOG: restauration terminée de l'archive 2019-07-23 16:55:42.251 P00 INFO: archive-get command begin 2.10: [00000002.history, pg_wal/RECOVERYHISTORY] --log-level-console=info --pg1-path=/var/lib/postgresql/11/apptra001 --repo1-path=/var/lib/pgbackrest --stanza=apptra001 2019-07-23 16:55:42.260 P00 INFO: found 00000002.history in the archive 2019-07-23 16:55:42.261 P00 INFO: archive-get command end: completed successfully (11ms) 2019-07-23 16:55:42.262 CEST [13648] LOG: restauration du journal de transactions « 00000002.history » à partir de l'archive 2019-07-23 16:55:42.370 CEST [13647] LOG: le système de bases de données est prêt pour accepter les connexions -- utilisateur postgres, on verifie l'archivage des WAL pgbackrest --log-level-console=info --stanza=apptra001 check 2019-07-23 16:58:15.444 P00 INFO: check command begin 2.10: --log-level-console=info --pg1-path=/var/lib/postgresql/11/apptra001 --pg1-port=5432 --repo1-path=/var/lib/pgbackrest --stanza=apptra001 2019-07-23 16:58:17.751 P00 INFO: WAL segment 00000003000000000000000D successfully stored in the archive at '/var/lib/pgbackrest/archive/apptra001/11-1/0000000300000000/00000003000000000000000D-c24041e7c6fa726cdb51472aefa466bd3d0aa336.gz' 2019-07-23 16:58:17.755 P00 INFO: check command end: completed successfully (2311ms) -- utilisateur postgres, une nouvelle timeline a ete ouverte, on relance un backup ! pgbackrest --log-level-console=info --compress-level=1 --process-max=4 --type=full --stanza=apptra001 backup


      Le PITR s'est bien passé. La seule difficulté est de ne pas se tromper de backup à employer avec la commande "pgbackrest restore" si le point de recover est antérieur au dernier backup effectué. Effectuer un "pgbackrest info" donne des détails sur chaque backup et permet de lever les doutes.
      Une nouvelle timeline (incarnation dans le vocabulaire Oracle Database) a été ouverte après le recover (équivalent d'un OPEN RESETLOGS pour les DBA Oracle). Les sessions de recover PostgreSQL, comme les sessions de recover Oracle Database, peuvent "traverser les incarnations" mais, néanmoins, je recommande d'effectuer immédiatement un premier backup dans la nouvelle timeline, avant la remise en production, pour simplifier les choses.

Mise à jour : 23/07/2019