PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Test automatizzato dei backup PostgreSQL

Avere backup regolari del database PostgreSQL da solo non è sufficiente per il ripristino di emergenza:è necessario assicurarsi che i file di backup siano accessibili e integri se e quando richiesto per una procedura di ripristino. Continua a leggere per vedere alcuni esempi di come impostare il test automatico dei backup di PostgreSQL.

Backup realizzati utilizzando pg_basebackup

Il pg_basebackup i backup contengono l'intera directory dei dati per un databasecluster. Questa directory è solitamente compressa in un tarball, a volte con un tarball aggiuntivo per i file WAL che sono stati creati dall'inizio del backup.

Per testare un tale pg_basebackup tarball, prima decomprimere il tarball in una directory vuota. Se è presente un tarball di file WAL separato, decomprimerlo nel pg_wal directory all'interno della nuova directory:

$ 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

Ora puoi avviare un processo del server PostgreSQL per questa directory:

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

(Nota:pg_ctl è uno strumento da riga di comando incluso nella distribuzione standard di Postgres. È disponibile ovunque sia Postgres stesso, simile agli altri strumenti inclusi come psql e pg_dump .Ulteriori informazioni su pg_ctl qui.)

Se c'è già un server PostgreSQL installato/in esecuzione su questa macchina, probabilmente vorrai iniziare su una porta diversa da quella predefinita 5432:

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

Se tutto è riuscito finora, ti consigliamo di verificare se i dati all'interno del tuo database ripristinato sono sani. Se si dispone di script di test automatici da eseguire sul database, ora sarebbe un buon momento per avviare almeno una piccola serie di test su questo database ripristinato. In caso contrario, puoi hackerare insieme alcuni controlli rapidi usando psql:

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

Il comando precedente esegue una semplice query su una tabella che dovrebbe esistere. Il codice di uscita di psql dovrebbe dirti se la query ha avuto successo o meno. Naturalmente, puoi eseguire query più complesse o eseguire un file .sql o anche uno script di test separato che si collegherà a questo database ed eseguirà test.

Al termine del test, puoi interrompere il processo del server Postgres con:

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

E ripulisci l'intera directory del cluster di database estratta:

$ rm -rf path/to/backup-test

Ecco come appare quando è tutto messo insieme:

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

Backup realizzati utilizzando pg_dump

Il pg_dump lo strumento (documenti) può essere utilizzato anche per creare backup:è più flessibile in quanto è possibile selezionare facoltativamente il database/schema/tabelle di cui eseguire il backup, al contrario di pg_basebackup che è un processo tutto o niente.

Con pg_dump , puoi generare un singolo .sql script o un .pgdmp binario file che contiene tutti i dati (ed eventualmente anche le istruzioni DDL per la creazione delle tabelle/indici ecc.). Per ripristinare tale file, è necessario connettersi a un server livedatabase ed eseguire i comandi SQL all'interno del file .sql/.pgdmp. Mentre puoi usare il normale psql per eseguire il file .sql, dovrai utilizzare pg_restore comando (docs) per eseguire il file .pgdmp.

Per testare tali backup, prima recuperiamo il file e quindi creiamo un nuovo cluster di database vuoto:

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

e avvia un server PostgreSQL su di esso, in ascolto sulla porta 6000 come prima:

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

È possibile generare pg_dump file che sono completamente autonomi, ma è anche possibile generarli per non esserlo. Pertanto, a seconda di come è stato generato il dump, potrebbero essere necessari alcuni passaggi di configurazione:

  • crea un database
  • crea tabelle, indici ecc.
  • Concedi privilegi

Una volta fatto, puoi usare psql o pg_restore per riportare in vita i dati:

# 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

Come in precedenza, a questo punto, è possibile effettuare dei test per garantire l'integrità dei dati archiviati.

Ecco come appare, tutto messo insieme:

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

Attenzione ai trigger

Durante il ripristino di un pg_dump backup, i dati vengono inseriti nelle tabelle, proprio come quando esegue un'applicazione. Se disponi di trigger che si collegano a servizi esterni per notificare gli inserimenti di righe, è meglio disabilitarli durante la procedura di ripristino.

Quando si invoca pg_dump per emettere file sql, puoi usare l'opzione--disable-triggers per dire a pg_dump per generare uno script per disabilitare i trigger durante l'inserimento.

Quando si richiama pg_restore su un database che ha già dei trigger, puoi usare il --disable-triggers in pg_restore per ottenere lo stesso effetto.

Test PITR

Il ripristino point-in-time (PITR) in Postgres si basa su un backup completo eseguito utilizzando pg_basebackup , e una sequenza di file WAL da quel momento fino al momento in cui si desidera eseguire il ripristino. Il test di PITR implica quindi il test del backup completo e dei successivi file WAL.

Per i test di backup automatizzati, non abbiamo un obiettivo di ripristino specifico. Tutti i file WAL archiviati dall'ultimo backup in poi fino a quello più recente devono essere testati. Il modo più semplice per verificarlo è seguire gli stessi passaggi del pg_basebackup metodo di prova, con un solo passaggio aggiuntivo. Dopo aver decompresso l'ultimo backup, recupera tutti i file WAL rilevanti e disponibili e inseriscili in pg_wal prima di avviare il server Postgres. Nello specifico:

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

Questo dovrebbe verificare se sia l'ultimo backup che i successivi file WAL sono corretti, in modo che possano essere utilizzati per PITR se e quando necessario.