Samotné pravidelné zálohování databáze PostgreSQL nestačí k obnově po havárii – musíte zajistit, aby soubory zálohy byly přístupné a v pořádku, pokud je to nutné pro postup obnovy. Čtěte dále a podívejte se na některé příklady, jak nastavit automatické testování záloh PostgreSQL.
Zálohy vytvořené pomocí pg_basebackup
pg_basebackup zálohy obsahují celý datový adresář pro databázový klastr. Tento adresář je obvykle zabalen do tarballu, někdy s dalším tarballem pro soubory WAL, které byly vytvořeny od začátku zálohování.
Chcete-li otestovat takový pg_basebackup tarball, nejprve rozbalte tarball do prázdného adresáře. Pokud existuje samostatný soubor tarball WAL, rozbalte jej do pg_wal
adresář v novém adresáři:
$ 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
Nyní můžete spustit proces serveru PostgreSQL pro tento adresář:
$ pg_ctl -D path/to/backup-test start
(Poznámka:pg_ctl je nástroj příkazového řádku, který je součástí standardní distribuce Postgres. Je dostupný všude tam, kde je samotný Postgres, podobně jako ostatní zahrnuté nástroje jako psql a pg_dump .Další informace o pg_ctl naleznete zde.)
Pokud je již na tomto počítači nainstalován/spuštěn PostgreSQL server, pravděpodobně budete chtít spustit na jiném portu, než je výchozí 5432:
$ pg_ctl -D path/to/backup-test -o "-p 6000 -k /tmp" start
Pokud se vše dosud podařilo, budete chtít zkontrolovat, zda jsou data ve vaší obnovené databázi v pořádku. Pokud máte automatické testovací skripty, které se mají spouštět proti vaší databázi, nyní by byl vhodný čas spustit alespoň malou sadu těchto testů proti této obnovené databázi. Pokud ne, můžete společně hacknout nějaké rychlé kontroly pomocí psql:
$ psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"
Výše uvedený příkaz provede jednoduchý dotaz na tabulku, která by měla existovat. Výstupní kód psql by vám měl říci, zda byl dotaz úspěšný nebo ne. Samozřejmě můžete spouštět složitější dotazy nebo spustit soubor .sql nebo dokonce samostatný testovací skript, který se připojí k této databázi a spustí testy.
Po dokončení testování můžete zastavit proces serveru Postgres pomocí:
$ pg_ctl -D path/to/backup-test stop
A vyčistěte celý adresář extrahovaného databázového clusteru:
$ rm -rf path/to/backup-test
Takto to vypadá, když je to všechno pohromadě:
#!/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
Zálohy vytvořené pomocí pg_dump
pg_dump nástroj (docs) lze také použít k vytváření záloh – to je flexibilnější v tom, že můžete volitelně vybrat databázi/schéma/tabulky, které chcete zálohovat, na rozdíl odpg_basebackup což je proces všechno nebo nic.
Pomocí pg_dump , můžete vygenerovat jeden .sql
skript nebo binární .pgdmp
soubor, který obsahuje všechna data (a volitelně také příkazy DDL pro vytváření tabulek/indexů atd.). Chcete-li obnovit takový soubor, musíte se připojit k serveru živé databáze a spustit příkazy SQL v souboru .sql/.pgdmp. I když můžete použít běžný psql ke spuštění souboru .sql budete muset použít pg_restore příkaz (docs) ke spuštění souboru .pgdmp.
Abychom takové zálohy otestovali, nejprve načteme soubor a poté vytvoříme nový prázdný cluster databáze:
$ rm -rf path/to/backup-test
$ pg_ctl -D path/to/backup-test initdb
a spusťte na něm PostgreSQL server, který naslouchá na portu 6000 jako předtím:
$ pg_ctl -D path/to/backup-test -o "-p 6000 -k /tmp" start
Je možné vygenerovat pg_dump soubory, které jsou plně samostatné, ale je také možné je vygenerovat tak, aby tomu tak nebylo. Proto v závislosti na tom, jak byl výpis generován, mohou být vyžadovány některé kroky nastavení:
- vytvořit databázi
- vytvářet tabulky, indexy atd.
- udělit oprávnění
Jakmile to uděláte, můžete buď použít psql nebo pg_restore aby data znovu ožila:
# 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
Stejně jako dříve, i v tomto okamžiku lze provést testy, aby se zajistila správnost uložených dat.
Tady je to, jak to vypadá, všechno dohromady:
#!/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.*
Pozor na spouštěče
Při obnově pg_dump zálohování, data se vkládají do tabulek, podobně jako když to dělá aplikace. Pokud máte spouštěče, které se připojují k externím službám, aby upozorňovaly na vkládání řádků, bylo by nejlepší je zakázat během procedury obnovy.
Při vyvolání pg_dump k odesílání souborů SQL můžete použít volbu--disable-triggers
sdělit pg_dump pro vygenerování skriptu pro deaktivaci spouštěčů při vkládání.
Při vyvolání pg_restore v databázi, která již spouštěče má, můžete použít --disable-triggers
v pg_restore k dosažení stejného efektu.
Testování PITR
Point-in-time-recovery (PITR) v Postgres spoléhá na úplnou zálohu pořízenou pomocí pg_basebackup a sekvence souborů WAL od tohoto bodu až do bodu v čase, kdy se chcete obnovit. Testování PITR proto zahrnuje testování plné zálohy i následných souborů WAL.
Pro testování automatického zálohování nemáme konkrétní cíl obnovy. Všechny archivované soubory WAL od poslední zálohy až po nejnovější by měly být otestovány. Nejjednodušší způsob, jak to otestovat, je postupovat podle stejných kroků jako u pg_basebackup zkušební metoda s pouze jedním dodatečným krokem. Po rozbalení nejnovější zálohy stáhněte všechny relevantní a dostupné soubory WAL a umístěte je do pg_wal
před spuštěním serveru Postgres. Konkrétně:
#!/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
To by mělo ověřit, zda jsou jak poslední záloha, tak následující soubory WAL dobré, aby je bylo možné v případě potřeby použít pro PITR.