Configurer des sauvegardes incrémentales avec PostgreSql – Restauration (Partie 3)



This content originally appeared on DEV Community and was authored by ZINSOU Trinité

🧭 Introduction

Mettre en place des sauvegardes, c’est essentiel. Mais savoir les restaurer efficacement en cas de besoin, c’est encore plus crucial. C’est ici que le PITR (Point In Time Recovery) entre en jeu, une fonctionnalité puissante offerte par PostgreSQL et parfaitement gérée par Barman.

Que ce soit pour corriger une erreur humaine, revenir avant un déploiement raté ou analyser l’état de la base à un instant précis, Barman permet de ramener PostgreSQL dans le passé, en rejouant uniquement les modifications jusqu’à un point bien défini.

Dans ce chapitre, nous allons explorer :

  • Ce qu’est concrètement le PITR,

  • Les prérequis pour qu’il fonctionne,

  • Et surtout, comment l’utiliser pas à pas avec Barman, de manière fiable.

Prêt à voyager dans le temps avec PostgreSQL ? C’est par ici 👇

🕰 C’est quoi le PITR (Point-In-Time Recovery) ?

Le Point-In-Time Recovery, ou PITR, est une fonctionnalité puissante de PostgreSQL qui permet de restaurer une base de données à un instant précis dans le passé.

C’est un peu comme une machine à remonter le temps 🕳🕒.

Imaginons qu’un bug ou une erreur humaine ait corrompu des données ce matin à 10h30. Grâce au PITR, vous pouvez restaurer la base exactement comme elle était à 09h29, juste avant le problème.

Pour que cela fonctionne, PostgreSQL enregistre toutes les écriture sur la base de données dans des fichiers appelés WALs (Write Ahead Logs). Ces fichiers contiennent l’historique des modifications apportées à la base.

Barman exploite ces fichiers pour rejouer l’histoire de la base jusqu’à l’instant choisi, à partir d’une sauvegarde complète. Il effectue ainsi un rétropédalage jusqu’à un instant désiré bien pris en compte par les sauvegardes existantes

🎯 RPO et RTO : Les deux piliers d’une bonne stratégie de sauvegarde/restauration

Quand on parle de continuité d’activité et de plan de reprise après sinistre (disaster recovery), deux notions sont essentielles à comprendre avant même de parler de sauvegarde ou d’outil comme Barman :

📌 Recovery Point Objective (RPO)

Le RPO, ou objectif de point de reprise, représente la quantité maximale de données que l’on peut se permettre de perdre en cas d’incident.

👉 Exemple :

Si vous acceptez de perdre au maximum 5 minutes de données, votre RPO est de 5 minutes. Cela implique que vos sauvegardes (ou la capture de vos WAL) doivent se faire au moins toutes les 5 minutes.

⏱ Recovery Time Objective (RTO)

Le RTO, ou objectif de temps de reprise, désigne la durée maximale acceptable d’indisponibilité du service après un incident.

👉 Exemple :

Si vous estimez qu’une interruption de service de 30 minutes est tolérable, alors votre RTO est de 30 minutes. Cela implique que vos outils et mécanisme de restauration (comme Barman et les automatisations que vous mettrez en place) doivent être capables de restorer et remettre le service en ligne dans ce délai.

⚖ Trouver le bon équilibre entre idéal et réalité

On aimerait tous avoir un RPO = 0 (aucune perte de données) et un RTO = 0 (aucun temps d’arrêt).

Mais dans la vraie vie, il faut souvent faire un compromis entre le coût et la criticité du service.

Par exemple :

  • Pour un site vitrine, un RPO/RTO de plusieurs heures peut être toléré.

  • Pour une application bancaire, chaque seconde compte : le RPO/RTO doit être quasi nul.

💡 RPO et RTO avec PostgreSQL et Barman

Bonne nouvelle : avec un stack open source bien configuré, il est possible de s’approcher de très bonnes performances :

  • RPO = 0 🎯

    Grâce à la réplication en streaming synchrone de PostgreSQL, vos données peuvent être protégées sans perte.

  • RTO minimal ⏱

    En combinant Barman pour les sauvegardes et repmgr pour la haute disponibilité, on peut atteindre un redémarrage quasi instantané en cas de problème.

🧰 Prérequis pour une restauration avec PITR

Avant de tenter une restauration point-in-time, quelques éléments doivent être en place pour que tout se passe bien :

1. Sauvegarde valide disponible

Vous devez avoir au moins une sauvegarde complète dans Barman. Elle servira de point de départ pour la restauration.

2. Archivage WAL activé

Le PITR repose sur la capacité à rejouer les WAL (Write Ahead Logs) jusqu’à un instant précis. Assurez-vous que l’archivage fonctionne correctement et que les fichiers sont bien présents dans le répertoire wals de Barman.

3. Espace disque suffisant

La restauration va créer une nouvelle copie de la base. Il est essentiel d’avoir suffisamment d’espace libre sur le serveur cible.

4. Horodatage ou XID de restauration

Pour déclencher un PITR, vous devez spécifier le point de restauration, soit :

* une date/heure ('2025-04-11 16:00:00'),

* un identifiant de transaction (XID),

* ou simplement la fin de la sauvegarde (si vous ne rejouez pas les WAL).

5. Environnement de test (optionnel mais recommandé)

Avant de lancer une restauration en production, il est fortement conseillé de tester la restauration dans un environnement isolé.

🔄 Récupération des données avec Barman (cas pratique)

Nous allons créer une table au niveau de notre base de données test et faire plusieurs manipulations afin d’éprouver notre système de sauvegarde.On va donc ajouter une table à notre base de données et y ajouter quelques lignes(tu peux te servir de ce script😉):

--- creation d'une table articles
CREATE TABLE articles (
  id SERIAL PRIMARY KEY,
  title TEXT,
  content TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

--- insertion de 20 lignes dans la table articles

INSERT INTO articles (title, content)
SELECT
  'Titre de l’article ' || i,
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
   Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
   Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
FROM generate_series(1, 20) AS s(i);

A cette étape on va refaire une sauvegarde incrémentale de notre base donnée avant de simuler un incident, une suppression involontaire de données par exemple toujours à l’aide de la commande barman backup pg(ici pg est le nom de notre serveur de base de données dans notre configuration barman), voici le retour à mon niveau:

# sur le serveur barman
$ barman backup pg
Starting backup using rsync-concurrent method for server pg in /var/lib/barman/pg/base/20250415T201516
Backup start at LSN: 0/14000028 (000000010000000000000014, 00000028)
Starting backup copy via rsync/SSH for 20250415T201516
Copy done (time: 2 seconds)
Asking PostgreSQL server to finalize the backup.
Backup size: 38.9 MiB. Actual size on disk: 4.8 MiB (-87.55% deduplication ratio).
Backup end at LSN: 0/14000100 (000000010000000000000014, 00000100)
Backup completed (start time: 2025-04-15 20:15:16.336556, elapsed time: 4 seconds)
Processing xlog segments from file archival for pg
    000000010000000000000013
    000000010000000000000014
    000000010000000000000014.00000028.backup

Note bien la date de fin de sauvegarde (start time+ temps ecoulé ou accesible avec barman show-backup pg id_backup ). Elle te servira de référence pour définir ton --target-time lors de la restauration.A présent simulons la perte de données:

--- suppression des articles d'id pairs
DELETE FROM articles WHERE id % 2 = 0;

--- vérifier que les éléments ont bien été supprimés
SELECT COUNT(id) FROM article; 

/*
--------------------------------------------
                OUTPUT
--------------------------------------------
*/
 count 
-------
    10
(1 row)

💥 Tous les articles avec un identifiant pair etant désormais supprimés (cet incident intervient peu de temps après ma dernière sauvegarde). C’est le moment idéal pour utiliser la récupération incrémentale et revenir à l’état initial. Avant de restorer nos données nous allons refaire une nouvelle sauvegarde et arreter notre serveur postgresql:

# sur le serveur barman
$ barman backup pg
Starting backup using rsync-concurrent method for server pg in /var/lib/barman/pg/base/20250415T201754
Backup start at LSN: 0/17000028 (000000010000000000000017, 00000028)
Starting backup copy via rsync/SSH for 20250415T201754
Copy done (time: 2 seconds)
Asking PostgreSQL server to finalize the backup.
Backup size: 38.9 MiB. Actual size on disk: 129.7 KiB (-99.67% deduplication ratio).
Backup end at LSN: 0/17000100 (000000010000000000000017, 00000100)
Backup completed (start time: 2025-04-15 20:17:55.167843, elapsed time: 4 seconds)
Processing xlog segments from file archival for pg
    000000010000000000000016
    000000010000000000000017
    000000010000000000000017.00000028.backup

$ barman list-backup pg
pg 20250415T201754 - Tue Apr 15 20:17:58 2025 - Size: 54.9 MiB - WAL Size: 0 B
pg 20250415T201516 - Tue Apr 15 20:15:19 2025 - Size: 54.9 MiB - WAL Size: 48.0 MiB
pg 20250413T113210 - Sun Apr 13 11:32:14 2025 - Size: 54.8 MiB - WAL Size: 32.0 MiB

# sur le serveur postgres
$ sudo service postgresql stop

A cette étape deux sauvegardes encadren notre incident, celles d’ids 20250415T201516 et 20250415T201754. La première est celle avec d’avant incident qui nous servira donc pour notre PITR.

La commande de restoration à taper sur le serveur barman est la suivante:

$ barman recover --remote-ssh-command "ssh postgres@192.168.58.11" --target-time="2025-04-15 20:17:58.270833+00:00" pg 20250415T201754 /var/lib/postgresql/12/main
Starting remote restore for server pg using backup 20250415T201754
Destination directory: /var/lib/postgresql/12/main
Remote command: ssh postgres@192.168.58.11
Doing PITR. Recovery target time: '2025-04-15 20:17:58.270833+00:00'
Using safe horizon time for smart rsync copy: 2025-04-15 20:17:54.690087+00:00
Copying the base backup.
Copying required WAL segments.
Generating recovery configuration
Identify dangerous settings in destination directory.

IMPORTANT
These settings have been modified to prevent data losses

postgresql.conf line 755: archive_command = false

WARNING
You are required to review the following options as potentially dangerous

postgresql.conf line 41: data_directory = '/var/lib/postgresql/12/main'     # use data in another directory
postgresql.conf line 43: hba_file = '/etc/postgresql/12/main/pg_hba.conf'   # host-based authentication file
postgresql.conf line 45: ident_file = '/etc/postgresql/12/main/pg_ident.conf'   # ident configuration file
postgresql.conf line 49: external_pid_file = '/var/run/postgresql/12-main.pid'          # write an extra PID file
postgresql.conf line 66: unix_socket_directories = '/var/run/postgresql'    # comma-separated list of directories
postgresql.conf line 102: ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
postgresql.conf line 104: ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
postgresql.conf line 740: include_dir = 'conf.d'            # include files ending in '.conf' from

Recovery completed (start time: 2025-04-16 15:14:41.903013, elapsed time: 8 seconds)

Your PostgreSQL server has been successfully prepared for recovery!

Les options de cette commande sont: --remote-ssh-command une commande ssh vers le serveur postgres, --target-time la date à laquelle restorée les données qui doit etre xxxxxxxxxxxxxx, server_name pour le nom du serveur, backup_id le nom du backup et destination_directory pour le dossier qui doit accepter les sauvegardes. Tu pourrais avoir plus d’options avec barman recover -h.

La recupération peut se faire dans n’importe quel dossier à part celui de base de postgres à condition de reconfiguer postgres pour pointer sur le dossier considéré. On peut après avoir à nouveau accès à nos données récupérées:

--- vérifier que les éléments ont bien été supprimés
SELECT COUNT(id) FROM article; 

/*
--------------------------------------------
                OUTPUT
--------------------------------------------
*/
 count 
-------
    20
(1 row)

🏁 Conclusion

Les erreurs humaines, les corruptions logicielles ou les incidents matériels ne sont pas une question de “si”, mais de “quand”. Dans ce contexte, la capacité à revenir à un état antérieur précis de ta base PostgreSQL est essentielle.

Avec Barman et la fonctionnalité de Point-In-Time Recovery (PITR), tu disposes d’un outil fiable, robuste et puissant pour répondre aux impératifs de continuité d’activité. En combinant les sauvegardes complètes aux fichiers WAL archivés, tu peux restaurer ta base à la seconde près, juste avant un incident.

Plus encore, tu l’as vu : ce processus peut s’automatiser, se tester, s’industrialiser; autant d’atouts pour renforcer la résilience de ton architecture PostgreSQL.


This content originally appeared on DEV Community and was authored by ZINSOU Trinité