PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Automatisiertes Testen von PostgreSQL-Backups

Regelmäßige Sicherungen Ihrer PostgreSQL-Datenbank allein reichen für die Notfallwiederherstellung nicht aus – Sie müssen sicherstellen, dass die Sicherungsdateien zugänglich und fehlerfrei sind, falls und wenn dies für einen Wiederherstellungsvorgang erforderlich ist. Lesen Sie weiter, um einige Beispiele für die Einrichtung automatischer Tests von PostgreSQL-Sicherungen zu sehen.

Mit pg_basebackup erstellte Sicherungen

Die pg_basebackup Backups enthalten das gesamte Datenverzeichnis für einen Datenbankcluster. Dieses Verzeichnis wird normalerweise in einen Tarball gepackt, manchmal mit einem zusätzlichen Tarball für WAL-Dateien, die seit Beginn der Sicherung erstellt wurden.

Um so ein pg_basebackup zu testen Tarball, entpacken Sie zuerst den Tarball in ein leeres Verzeichnis. Wenn es einen separaten WAL-Datei-Tarball gibt, entpacken Sie diesen in pg_wal Verzeichnis innerhalb des neuen Verzeichnisses:

$ 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

Sie können jetzt einen PostgreSQL-Serverprozess für dieses Verzeichnis starten:

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

(Hinweis:pg_ctl ist ein Befehlszeilentool, das in der Standard-Postgres-Distribution enthalten ist. Es ist überall dort verfügbar, wo es Postgres selbst gibt, ähnlich wie die anderen enthaltenen Tools wie psql und pg_dump .Erfahren Sie hier mehr über pg_ctl.)

Wenn auf diesem Computer bereits ein PostgreSQL-Server installiert ist/läuft, sollten Sie wahrscheinlich auf einem anderen Port als dem Standardport 5432 starten:

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

Wenn bisher alles erfolgreich war, sollten Sie überprüfen, ob die Daten in Ihrer wiederhergestellten Datenbank gesund sind. Wenn Sie über automatisierte Testskripts verfügen, die für Ihre Datenbank ausgeführt werden sollen, wäre jetzt ein guter Zeitpunkt, um zumindest eine kleine Gruppe dieser Tests für diese wiederhergestellte Datenbank zu starten. Wenn nicht, können Sie einige Quickchecks mit psql zusammenhacken:

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

Der obige Befehl führt eine einfache Abfrage einer Tabelle durch, die vorhanden sein sollte. Der Exit-Code von psql sollte Ihnen sagen, ob die Abfrage erfolgreich war oder nicht. Natürlich können Sie komplexere Abfragen oder eine .sql-Datei oder sogar ein separates Testskript ausführen, das eine Verbindung zu dieser Datenbank herstellt und Tests durchführt.

Wenn Sie mit dem Testen fertig sind, können Sie den Postgres-Serverprozess stoppen mit:

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

Und bereinigen Sie das gesamte extrahierte Datenbank-Cluster-Verzeichnis:

$ rm -rf path/to/backup-test

So sieht es aus, wenn alles zusammengefügt ist:

#!/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

Mit pg_dump erstellte Sicherungen

Der pg_dump tool (docs) kann auch zum Erstellen von Backups verwendet werden – dies ist flexibler, da Sie optional die Datenbank/das Schema/die Tabellen auswählen können, die Sie sichern möchten, im Gegensatz zu pg_basebackup das ist ein Alles-oder-Nichts-Prozess.

Mit pg_dump , können Sie eine einzelne .sql generieren Skript oder ein binäres .pgdmp Datei, die alle Daten enthält (und optional auch die DDL-Anweisungen zum Erstellen der Tabellen/Indizes etc.). Um eine solche Datei wiederherzustellen, müssen Sie eine Verbindung zu einem Live-Datenbankserver herstellen und die SQL-Befehle in der .sql/.pgdmp-Datei ausführen. Während Sie das reguläre psql verwenden können Um die .sql-Datei auszuführen, müssen Sie pg_restore verwenden Befehl (docs) zum Ausführen der .pgdmp-Datei.

Um solche Sicherungen zu testen, holen wir uns zuerst die Datei und erstellen dann einen neuen, leeren Datenbank-Cluster:

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

und starten Sie darauf einen PostgreSQL-Server, der wie zuvor auf Port 6000 lauscht:

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

Es ist möglich, pg_dump zu generieren Dateien, die vollständig in sich geschlossen sind, aber es ist auch möglich, sie so zu generieren, dass sie es nicht sind. Je nachdem, wie der Dump generiert wurde, sind daher möglicherweise einige Einrichtungsschritte erforderlich:

  • eine Datenbank erstellen
  • Tabellen, Indizes usw. erstellen
  • Privilegien gewähren

Danach können Sie entweder psql verwenden oder pg_restore um die Daten wieder zum Leben zu erwecken:

# 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

Wie zuvor können an dieser Stelle Tests durchgeführt werden, um die Korrektheit der wiederhergestellten Daten sicherzustellen.

So sieht es zusammen aus:

#!/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.*

Achten Sie auf Trigger

Beim Wiederherstellen eines pg_dump Datensicherung werden Daten in Tabellen eingefügt, ähnlich wie bei einer Anwendung. Wenn Sie Trigger haben, die sich mit externen Diensten verbinden, um über das Einfügen von Zeilen zu informieren, ist es am besten, sie während des Restore-Vorgangs zu deaktivieren.

Beim Aufruf von pg_dump Um SQL-Dateien auszugeben, können Sie die Option--disable-triggers verwenden pg_dump mitzuteilen zum Generieren eines Skripts zum Deaktivieren der Trigger beim Einfügen.

Beim Aufruf von pg_restore Auf einer Datenbank, die bereits Trigger hat, können Sie --disable-triggers verwenden in pg_restore um den gleichen Effekt zu erzielen.

PITR-Tests

Point-in-Time-Recovery (PITR) in Postgres basiert auf einer vollständigen Sicherung, die mit pg_basebackup erstellt wird , und eine Folge von WAL-Dateien von diesem Zeitpunkt bis zu dem Zeitpunkt, zu dem Sie wiederherstellen möchten. Das Testen von PITR umfasst daher das Testen der vollständigen Sicherung sowie der nachfolgenden WAL-Dateien.

Für automatisierte Sicherungstests haben wir kein spezifisches Wiederherstellungsziel. Alle archivierten WAL-Dateien ab der letzten Sicherung bis zur neuesten sollten getestet werden. Am einfachsten können Sie dies testen, indem Sie denselben Schritten wie für pg_basebackup folgen Prüfmethode mit nur einem zusätzlichen Schritt. Holen Sie nach dem Entpacken der neuesten Sicherung alle relevanten und verfügbaren WAL-Dateien und platzieren Sie sie in pg_wal bevor Sie den Postgres-Server starten. Konkret:

#!/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

Dies sollte überprüfen, ob sowohl die letzte Sicherung als auch nachfolgende WAL-Dateien in Ordnung sind, sodass sie bei Bedarf für PITR verwendet werden können.