PostgreSQL : un pg_dump n’est pas une sauvegarde tant que la restauration n’a pas été testée
Un fichier .dump existe, le cron est passé au vert et le stockage n’est pas plein. Sur le papier, tout va bien. En pratique, cela prouve seulement qu’un fichier a été créé. La vraie question est plus simple : peut-on repartir de ce fichier, proprement et dans un délai acceptable ?
Avec PostgreSQL, pg_dump est un excellent outil de sauvegarde logique. Mais sans restauration de contrôle, vérifications fonctionnelles et stratégie adaptée au niveau de perte acceptable, il reste une promesse non testée. Voici une méthode concrète pour passer du « ça devrait marcher » à une sauvegarde réellement exploitable.
Ce que pg_dump sauvegarde vraiment
pg_dump produit une exportation logique d’une base : schémas, tables, données et objets contenus dans cette base. PostgreSQL réalise cette exportation de manière cohérente, même si l’application continue à lire et écrire pendant l’opération.
Le format personnalisé est généralement pratique, car il est compressé par défaut et permet à pg_restore de sélectionner ou réordonner les objets au moment de la restauration :
pg_dump \
--format=custom \
--file=app-2026-09-28.dump \
--dbname=app
Évitez de placer un mot de passe directement dans la commande ou dans une URL conservée par l’historique du shell. Utilisez plutôt un fichier .pgpass correctement protégé, un service PostgreSQL ou le mécanisme de secrets de votre environnement.
Attention aussi à la version du client : un pg_dump ancien ne peut pas sauvegarder un serveur d’une version majeure plus récente. Contrôlez au minimum le binaire réellement appelé par l’automatisation :
pg_dump --version
Un contrôle de fichier ne remplace pas une restauration
On peut commencer par vérifier que l’archive est lisible et contient bien un catalogue d’objets :
pg_restore --list app-2026-09-28.dump > app-2026-09-28.list
C’est utile pour détecter un fichier manifestement invalide, mais cela ne valide ni les données, ni les dépendances, ni le bon fonctionnement de l’application. Une archive peut être listable et échouer pendant la création d’une extension, l’attribution d’un propriétaire ou le chargement d’une contrainte.
Ajoutez également une empreinte au moment où le fichier est produit, puis vérifiez-la après son transfert ou avant la restauration :
sha256sum app-2026-09-28.dump > app-2026-09-28.dump.sha256
sha256sum --check app-2026-09-28.dump.sha256
Cette empreinte détecte une modification ou une corruption du fichier. Elle ne dit pas si le contenu sauvegardé est complet ni si le scénario de reprise est cohérent.
Ne pas oublier les rôles et les objets globaux
Une sauvegarde réalisée avec pg_dump concerne une base. Les rôles et les tablespaces appartiennent au cluster PostgreSQL et ne sont donc pas inclus dans ce fichier. Pour les conserver séparément :
pg_dumpall \
--globals-only \
--file=globals-2026-09-28.sql
Gardez ce fichier avec les sauvegardes concernées, mais ne le rejouez pas à l’aveugle sur un serveur partagé : il peut créer ou modifier des objets globaux. Pour un exercice complet, restaurez-le dans une instance PostgreSQL réellement isolée.
Faire un test de restauration sans toucher à la production
Le test doit se faire sur une base jetable, dans un environnement isolé et avec une capacité disque suffisante. Jamais par-dessus la base de production « juste pour voir ».
Pour un contrôle fonctionnel courant sur une instance de test :
createdb --template=template0 app_restore_test
pg_restore \
--exit-on-error \
--single-transaction \
--no-owner \
--no-privileges \
--dbname=app_restore_test \
app-2026-09-28.dump
--exit-on-error évite de masquer une erreur au milieu d’une longue sortie. --single-transaction garantit que la restauration est entièrement appliquée ou annulée. Cette option n’est pas compatible avec une restauration parallèle via --jobs.
Les options --no-owner et --no-privileges sont pratiques lorsque les rôles de production n’existent pas dans l’environnement de test. Elles permettent de vérifier le schéma, les données et l’application, mais ce n’est pas un exercice de reprise à l’identique. Pour valider les propriétaires et les droits, il faut un cluster isolé contenant aussi les objets globaux.
Quoi vérifier après le retour à zéro erreur ?
Une commande terminée sans erreur n’est que la première étape. La base restaurée doit ensuite être interrogée comme une vraie base applicative.
- Contrôler la présence des schémas, extensions, vues, fonctions, séquences et contraintes attendus.
- Comparer quelques volumes représentatifs : utilisateurs, commandes, événements ou autres tables métier importantes.
- Vérifier les lignes les plus récentes pour confirmer que la sauvegarde couvre bien la période annoncée.
- Lancer les contrôles d’intégrité propres à l’application et un test de lecture ciblé.
- Examiner les journaux de restauration : une absence de code d’erreur ne remplace pas l’analyse des avertissements.
- Mesurer la durée totale, du téléchargement de l’archive au retour du service.
Le meilleur test reste un petit scénario reproductible : démarrage de l’application sur la base restaurée, authentification avec un compte de test, lecture de plusieurs écrans importants et, si l’environnement le permet, une écriture sans effet métier réel.
RPO, RTO et limite importante de pg_dump
Deux chiffres doivent être décidés avant l’incident. Le RPO correspond à la quantité de données que l’on accepte de perdre. Le RTO correspond au temps acceptable pour remettre le service en état.
Si un dump est créé toutes les nuits, une panne en fin de journée peut faire perdre presque une journée de données. Et si la restauration prend quatre heures alors que le service doit repartir en trente minutes, la sauvegarde fonctionne techniquement mais ne répond pas au besoin.
Pour revenir à un instant précis, pg_dump ne suffit pas. PostgreSQL prévoit la sauvegarde physique de base associée à l’archivage continu des journaux WAL pour mettre en place une restauration à un point dans le temps, ou PITR. Cette architecture demande davantage de stockage, de surveillance et surtout des exercices réguliers.
Automatiser la preuve, pas seulement la copie
Une chaîne saine ne se contente pas de lancer pg_dump. Elle surveille le code de sortie, la taille du fichier, sa durée de création, son empreinte, sa réplication vers un autre emplacement et l’ancienneté de la dernière sauvegarde valide. Une archive anormalement petite ou un traitement soudainement deux fois plus long mérite une alerte.
Planifiez aussi une restauration automatique sur un environnement jetable, puis un exercice manuel plus complet à intervalle régulier. Conservez le compte rendu : date, fichier utilisé, version de PostgreSQL, durée, contrôles passés et anomalies rencontrées. Le jour où ça casse, cette documentation vaut largement plus qu’un dossier rempli de dumps jamais ouverts.
En clair
pg_dump est une brique solide, mais la sauvegarde est un processus complet : produire, transférer, conserver, restaurer, vérifier et mesurer. Tant que le dernier maillon n’a pas été testé, on ne sait pas réellement si les données sont récupérables. Faites au moins une restauration aujourd’hui : si elle échoue, autant le découvrir pendant que la production fonctionne encore.