PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Test automatisé des sauvegardes PostgreSQL

Avoir des sauvegardes régulières de votre base de données PostgreSQL seule n'est pas suffisant pour la reprise après sinistre - vous devez vous assurer que les fichiers de sauvegarde sont accessibles et sains si et quand cela est nécessaire pour une procédure de restauration. Lisez la suite pour voir des exemples de configuration de tests automatisés de sauvegardes PostgreSQL.

Sauvegardes effectuées avec pg_basebackup

Le pg_basebackup les sauvegardes contiennent l'intégralité du répertoire de données d'un cluster de bases de données. Ce répertoire est généralement compressé dans une archive tar, parfois avec une archive tar supplémentaire pour les fichiers WAL créés depuis le début de la sauvegarde.

Pour tester un tel pg_basebackup tarball, décompressez d'abord l'archive tar dans un répertoire vide. S'il existe une archive tar de fichier WAL séparée, décompressez-la dans pg_wal répertoire à l'intérieur du nouveau répertoire :

$ mkdir backup-test
$ cd backup-test
$ tar --no-same-owner xvf /path/to/base.tar.gz
$ mkdir -p pg_wal
$ cd pg_wal
$ tar --no-same-owner xvf /path/to/pg_wal.tar.gz

Vous pouvez maintenant démarrer un processus serveur PostgreSQL pour ce répertoire :

$ pg_ctl -D path/to/backup-test start

(Remarque :pg_ctl est un outil en ligne de commande inclus dans la distribution standard de Postgres. Il est disponible partout où Postgres lui-même est, similaire aux autres outils inclus comme psql et pg_dump .En savoir plus sur pg_ctl ici.)

S'il y a déjà un serveur PostgreSQL installé/en cours d'exécution sur cette machine, vous voudrez probablement démarrer sur un port autre que le 5432 par défaut :

$ pg_ctl -D path/to/backup-test -o "-p 6000 -k /tmp" start

Si tout a réussi jusqu'à présent, vous voudrez vérifier si les données de votre base de données restaurée sont saines. Si vous avez des scripts de test automatisés à exécuter sur votre base de données, le moment est venu de lancer au moins un petit ensemble de ces tests sur cette base de données restaurée. Sinon, vous pouvez pirater ensemble quelques vérifications rapides en utilisant psql :

$ psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

La commande ci-dessus effectue une requête simple sur une table qui devrait exister. Le code de sortie de psql devrait vous indiquer si la requête a réussi ou non. Bien sûr, vous pouvez exécuter des requêtes plus complexes, ou exécuter un fichier .sql, ou même un script de test séparé qui se connectera à cette base de données et exécutera des tests.

Lorsque vous avez terminé les tests, vous pouvez arrêter le processus du serveur Postgres avec :

$ pg_ctl -D path/to/backup-test stop

Et nettoyez l'intégralité du répertoire du cluster de base de données extrait :

$ rm -rf path/to/backup-test

Voici à quoi ça ressemble quand tout est assemblé :

#!/bin/bash

# exit immediately if any step fails 
set -eo pipefail

# fetch the latest backup
# TODO: copy out base.tar.gz and pg_wal.tar.gz of latest backup

# create a directory to work in
BACKUP_DIR=/tmp/backup-test
rm -rf $BACKUP_DIR
mkdir $BACKUP_DIR

# unpack the backup archives
tar -C $BACKUP_DIR --no-same-owner xvf /path/to/base.tar.gz
mkdir -p $BACKUP_DIR/pg_wal
tar -C $BACKUP_DIR/pg_wal --no-same-owner xvf /path/to/pg_wal.tar.gz

# start a new Postgres server for the cluster on port 6000
pg_ctl -D $BACKUP_DIR -o "-p 6000 -k /tmp" start

# perform a simple test
psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

# shutdown the server
pg_ctl -D $BACKUP_DIR stop

# cleanup the files
rm -rf $BACKUP_DIR /path/to/base.tar.gz /path/to/pg_wal.tar.gz

Sauvegardes effectuées avec pg_dump

Le pg_dump L'outil (docs) peut également être utilisé pour créer des sauvegardes - ceci est plus flexible dans la mesure où vous pouvez éventuellement sélectionner la base de données/le schéma/les tables que vous souhaitez sauvegarder, par opposition à pg_basebackup qui est un processus tout ou rien.

Avec pg_dump , vous pouvez générer un seul .sql script ou un binaire .pgdmp fichier contenant toutes les données (et éventuellement aussi les instructions DDL pour la création des tables/index, etc.). Pour restaurer un tel fichier, vous devez vous connecter à un serveur livedatabase et exécuter les commandes SQL dans le fichier .sql/.pgdmp. Bien que vous puissiez utiliser le psql normal pour exécuter le fichier .sql, vous devrez utiliser le pg_restore commande (docs) pour exécuter le fichier .pgdmp.

Pour tester de telles sauvegardes, nous récupérons d'abord le fichier, puis créons un nouveau cluster de base de données vide :

$ rm -rf path/to/backup-test
$ pg_ctl -D path/to/backup-test initdb

et démarrez un serveur PostgreSQL dessus, en écoutant sur le port 6000 comme avant :

$ pg_ctl -D path/to/backup-test -o "-p 6000 -k /tmp" start

Il est possible de générer pg_dump des fichiers entièrement autonomes, mais il est également possible de les générer pour qu'ils ne le soient pas. Par conséquent, selon la façon dont le vidage a été généré, certaines étapes de configuration peuvent être nécessaires :

  • créer une base de données
  • créer des tables, des index, etc.
  • accorder des privilèges

Une fois cela fait, vous pouvez soit utiliser psql ou pg_restore pour donner vie à la databack :

# for .sql files
$ psql -p 6000 -h /tmp -v ON_ERROR_STOP=1 -1 -b -f path/to/dump.sql 

# for .pgdmp files
$ pg_restore -p 6000 -h /tmp -d mydb -C -1 -f path/to/dump.pgdmp

Comme auparavant, à ce stade, des tests peuvent être effectués pour garantir l'intégrité des données stockées.

Voici à quoi cela ressemble, tous assemblés :

#!/bin/bash

# exit immediately if any step fails 
set -eo pipefail

# fetch the latest dump
# TODO: copy out the dump.sql or dump.pgdmp of latest backup

# create an empty database cluster
BACKUP_DIR=/tmp/backup-test
rm -rf $BACKUP_DIR
pg_ctl -D $BACKUP_DIR initdb

# start a new Postgres server for the cluster on port 6000
pg_ctl -D $BACKUP_DIR -o "-p 6000 -k /tmp" start

# TODO: perform any specific setup steps here

# restore the file, .sql:
psql -p 6000 -h /tmp -v ON_ERROR_STOP=1 -1 -b -f path/to/dump.sql 
# or .pgdmp:
pg_restore -p 6000 -h /tmp -d mydb -C -1 -f path/to/dump.pgdmp

# perform a simple test
psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

# shutdown the server
pg_ctl -D $BACKUP_DIR stop

# cleanup the files
rm -rf $BACKUP_DIR /path/to/dump.*

Attention aux déclencheurs

Lors de la restauration d'un pg_dump sauvegarde, les données sont insérées dans des tables, un peu comme lorsqu'une application le fait. Si vous avez des déclencheurs qui se connectent à des services externes pour notifier les insertions de lignes, il serait préférable de les désactiver lors de la procédure de restauration.

Lors de l'appel de pg_dump pour émettre des fichiers sql, vous pouvez utiliser l'option--disable-triggers dire à pg_dump pour générer un script pour désactiver les déclencheurs lors de l'insertion.

Lors de l'appel de pg_restore sur une base de données qui a déjà des déclencheurs, vous pouvez utiliser le --disable-triggers dans pg_restore pour obtenir le même effet.

Test PITR

La récupération ponctuelle (PITR) dans Postgres repose sur une sauvegarde complète effectuée à l'aide de pg_basebackup , et une séquence de fichiers WAL à partir de ce moment jusqu'au moment où vous souhaitez effectuer la restauration. Le test de PITR implique donc de tester la sauvegarde complète ainsi que les fichiers WAL suivants.

Pour les tests de sauvegarde automatisés, nous n'avons pas d'objectif de récupération spécifique. Tous les fichiers WAL archivés depuis la dernière sauvegarde jusqu'à la plus récente doivent être testés. Le moyen le plus simple de tester cela est de suivre les mêmes étapes que pour le pg_basebackup méthode de test, avec une seule étape supplémentaire. Après avoir décompressé la dernière sauvegarde, récupérez tous les fichiers WAL pertinents et disponibles et placez-les dans pg_wal avant de démarrer le serveur Postgres. Plus précisément :

#!/bin/bash

# exit immediately if any step fails 
set -eo pipefail

# fetch the latest backup
# TODO: copy out base.tar.gz and pg_wal.tar.gz of latest backup

# create a directory to work in
BACKUP_DIR=/tmp/backup-test
rm -rf $BACKUP_DIR
mkdir $BACKUP_DIR

# unpack the backup archives
tar -C $BACKUP_DIR --no-same-owner xvf /path/to/base.tar.gz
mkdir -p $BACKUP_DIR/pg_wal
tar -C $BACKUP_DIR/pg_wal --no-same-owner xvf /path/to/pg_wal.tar.gz

# --> this is the new extra step <--
# TODO: fetch all WAL files from the WAL archive since the last
# backup, and place them in $BACKUP_DIR/pg_wal

# start a new Postgres server for the cluster on port 6000
pg_ctl -D $BACKUP_DIR -o "-p 6000 -k /tmp" start

# perform a simple test
psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

# shutdown the server
pg_ctl -D $BACKUP_DIR stop

# cleanup the files
rm -rf $BACKUP_DIR /path/to/base.tar.gz /path/to/pg_wal.tar.gz

Cela devrait vérifier si la dernière sauvegarde et les fichiers WAL suivants sont bons, afin qu'ils puissent être utilisés pour PITR si et quand nécessaire.