sql >> Databáze >  >> RDS >> PostgreSQL

Bylo by možné při provádění PITR pozastavit/obnovit v PostgreSQL?

Ano, skutečně možné a chytře řešené PostgreSQL. Abych to mohl demonstrovat, nejprve musím přejít po standardní technice Point in Time Recovery v PostgreSQL. Různé knihy/články/blogy byly mimořádně dobře ukázány mimořádnými autory, a proto nebudu zacházet do podrobností o tom, jak to udělat, ale zamířím přímo k tématu, tj. jak se zastavit při zotavování stejnou technikou. Pravděpodobně jsem uvedl matematický výraz z PITR jako „PITR =(poslední záloha souborového systému (LFB) + archivy WAL vygenerované po LFB + nearchivované WAL v aktuálních $PGDATA/pg_xlogs)“. Pro lepší pochopení jsem to uvedl do grafu, ve světle skutečnosti, že to více objasňuje myšlenku:(Omlouvám se, tento blog je trochu dlouhý, nevědomky se to stalo při podrobnostech konceptu)

PITR kroky, které budou následovat s drobnými změnami, o kterých budu brzy mluvit:

Krok 1. Obnovte nejnovější zálohu na úrovni souborového systému (FSB) do libovolného umístění, kde je plánováno obnovení.
Krok 2. Pokud je FSB tar, pak jej rozbalte a vyčistěte adresář pg_xlog ponechte archive_status. Pokud zálohování tento adresář vyloučilo, vytvořte prázdný adresář pg_xlog na FSB.
Krok 3. Zkopírujte nearchivované WAL z havarovaného clusteru $PGDATA/pg_xlog do $FSB/pg_xlog (krok 2)
Krok 4. Odstraňte postmaster.pid z adresáře FSB.
Krok 5. Vytvořte soubor recovery.conf v adresáři FSB.
Krok 6. Spusťte cluster (FSB).

Měli bychom si položit otázku, kdy je vyžadováno pozastavení obnovy?. Možná, aby se zabránilo vícenásobnému obnovení základny nebo obnovení po přehrání vpřed, ale mezitím zkontrolujte nebo vraťte data konkrétní tabulky nebo zájem, abyste viděli, jak dalece se obnovila :). Pamatujte, že pauza v obnově znamená, že umožňuje připojení během obnovy. Abych to nastínil, reprodukoval jsem situaci v grafu zlepšení konkrétních řádků tabulky až do neštěstí.

Z výše uvedeného diagramu je příjemné, že řádky DEMO tabulky byly 10 00 000 při zálohování na úrovni souborového systému ($ PGDATA) a 40 00 000 řádků před havárií. Ve svém místním virtuálním počítači jsem vytvořil situaci na základě TIME namísto data.

Předběžné:
1. Záloha na úrovni souborového systému, když DEMO tabulky mají 10 00 000 řádků.
2. Od tohoto okamžiku se WAL archivuje před zhroucením, kde DEMO tabulka má 40 00 000 řádků.
3. Umístění archivů WAL:/opt/PostgreSQL/9.3/archives.
4. Datový adresář:/opt/PostgreSQL/9.3/data (PGDATA)
5. Umístění zálohy:/opt/PostgreSQL/9.3/backups

Mějte na paměti, že práce s pozastavením obnovy vyžaduje povinné změny v hlavním clusteru ($PGDATA) „wal_level“ nastavené na „hot_standby“ a na clusteru obnovy (záloha na úrovni systému souborů) „hot_standby“ nastaveném na „ON“. Provedl jsem tyto změny v hlavním clusteru, restartoval jsem cluster, aby se projevily, a spustil zálohování. Pokud vám nevadí, poznamenejte si, že jde pouze o demo, takže moje archivy WAL nemusí být gigantické, protože jsou v několika počtech. Také jsem zde uvedl archivy WAL, které byly vygenerovány od okamžiku zálohování do pádu.

-bash-4.1$ psql -c "select count(*), now() from demo;"
count | now
---------+-------------------------------
1000000 | 2014-04-04 15:06:04.036928-07
(1 row)

-bash-4.1$ pg_basebackup -D /opt/PostgreSQL/9.3/backup/data_pitr -- I have my $PGDATA, $PGUSER, $PGPORT set, so its a straight command in my case
NOTICE: pg_stop_backup complete, all required WAL segments have been archived

Aktuální stav archivů WAL a $PGDATA/pg_xlog

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/archives
-rw------- 1 postgres postgres 16M Apr 4 16:01 00000001000000000000001C
-rw------- 1 postgres postgres 16M Apr 4 16:01 00000001000000000000001D
-rw------- 1 postgres postgres 289 Apr 4 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001E

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/data/pg_xlog | tail -4
-rw------- 1 postgres postgres 289 Apr 4 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001E
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001F
drwx------ 2 postgres postgres 4.0K Apr 4 16:13 archive_status

Dobře, máme záložní kopii, která umožňuje VLOŽIT několik záznamů ve třech částech se zaznamenáváním času, takže to pomůže pozastavit obnovu a navíc vidět WAL vytvořené z doby FSB.

-bash-4.1$ psql -c "insert into demo values (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "select count(*),now() from demo;"
count | now
---------+-------------------------------
2000000 | 2014-04-04 16:06:34.941615-07
(1 row)
-bash-4.1$ psql -c "insert into demo values (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "select count(*),now() from demo;"
count | now
---------+-------------------------------
3000000 | 2014-04-04 16:10:31.136725-07
(1 row)
-bash-4.1$ psql -c "insert into demo values (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "select count(*),now() from demo;"
count | now
---------+-------------------------------
4000000 | 2014-04-04 16:13:00.136725-07
(1 row)

Zkontrolujte počet WAL vytvořených během INSERT.

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/archives
-rw------- 1 postgres postgres 289 Apr 4 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001E
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001F
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000020
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000021
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000022
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000023
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000024
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000025
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000026
-rw------- 1 postgres postgres 16M Apr 4 16:10 000000010000000000000027
-rw------- 1 postgres postgres 16M Apr 4 16:10 000000010000000000000028
-rw------- 1 postgres postgres 16M Apr 4 16:10 000000010000000000000029
-rw------- 1 postgres postgres 16M Apr 4 16:10 00000001000000000000002A
-rw------- 1 postgres postgres 16M Apr 4 16:13 00000001000000000000002B

Předpokládejme, že v tomto okamžiku došlo k nehodě a musíte provést obnovu pomocí archivů FSB + WAL + nearchivovaných WAL (pokud existují). Během obnovy se chci třikrát pozastavit, abych viděl každou obnovu 20 00 000, 30 00 000 a 40 00 000 řádků DEMO tabulky připojením k databázi v režimu pouze pro čtení. Pro každé obnovení obnovy je třeba restartovat cluster obnovy přechodem na novou časovou osu v recovery.conf/recovery_target_time. Také v $FSB/postgresql.conf musíme nastavit hot_standby=on. Zde je můj soubor recovery.conf:

-bash-4.1$ more recovery.conf
pause_at_recovery_target = true
#recovery_target_time = '2014-04-04 16:06:34' # For 2 lakh records
#recovery_target_time = '2014-04-04 16:10:31' # For 3 lakh records
#recovery_target_time = '2014-04-04 16:13:00' # For 4 lakh records
restore_command = 'cp /opt/PostgreSQL/9.3/archives/%f %p'

Začněme obnovovat 20 00 000 záznamů:

-bash-4.1$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_pitr/ start
server starting

Now in logs:

-bash-4.1$ more postgresql-2014-04-04_162524.log
2014-04-04 16:25:24 PDT-24187---[] LOG: starting point-in-time recovery to 2014-02-06 18:48:56-08
2014-04-04 16:25:24 PDT-24187---[] LOG: restored log file "00000001000000000000001E" from archive
2014-04-04 16:25:24 PDT-24187---[] LOG: redo starts at 0/1E0000C8
2014-04-04 16:25:24 PDT-24187---[] LOG: consistent recovery state reached at 0/1E000190
2014-04-04 16:25:24 PDT-24185---[] LOG: database system is ready to accept read only connections
2014-04-04 16:25:24 PDT-24187---[] LOG: restored log file "00000001000000000000001F" from archive
2014-04-04 16:25:24 PDT-24187---[] LOG: restored log file "000000010000000000000020" from archive
2014-04-04 16:25:25 PDT-24187---[] LOG: restored log file "000000010000000000000021" from archive
2014-04-04 16:25:25 PDT-24187---[] LOG: restored log file "000000010000000000000022" from archive
2014-04-04 16:25:25 PDT-24187---[] LOG: recovery stopping before commit of transaction 1833, time 2014-04-04 16:06:23.893487-07
2014-04-04 16:25:25 PDT-24187---[] LOG: recovery has paused
2014-04-04 16:25:25 PDT-24187---[] HINT: Execute pg_xlog_replay_resume() to continue

Skvělé, v protokolech uvidíte, že je pozastaveno, a inteligentní TIP s výzvou k obnovení. Zde, pokud byla obnova uspokojivá, můžete ji obnovit voláním „select pg_xlog_replay_resume();“ (můžete si to ověřit). Nyní nepokračujme, ale zkontrolujte počet řádků obnovených připojením k serveru.

-bash-4.1$ psql -c "select count(*),pg_is_in_recovery() from demo;"
count | pg_is_in_recovery
---------+-------------------
2000000 | t
(1 row)

Dobře, došlo to k bodu a zastavilo se tam, kde jsem žádal. Udělejme další krok vpřed, abychom obnovili 30 00 000 řádků. Nyní nastavte další časovou osu v recovery.conf/recovery_target_time a restartujte cluster.

2014-04-04 16:28:40 PDT-24409---[] LOG:  restored log file "00000001000000000000002A" from archive
2014-04-04 16:28:40 PDT-24409---[] LOG: recovery stopping before commit of transaction 1836, time 2014-04-04 16:10:40.141175-07
2014-04-04 16:28:40 PDT-24409---[] LOG: recovery has paused
2014-04-04 16:28:40 PDT-24409---[] HINT: Execute pg_xlog_replay_resume() to continue.

-bash-4.1$ psql -c "select count(*),pg_is_in_recovery() from demo;"
count | pg_is_in_recovery
---------+-------------------
3000000 | t
(1 row)

Pěkné..., zkusme se naposledy zastavit na 40 00 000 řádcích.

2014-04-04 20:09:07 PDT-4723---[] LOG:  restored log file "00000001000000000000002B" from archive
cp: cannot stat `/opt/PostgreSQL/9.3/archives/00000001000000000000002C': No such file or directory
2014-04-04 20:09:07 PDT-4723---[] LOG: redo done at 0/2B0059A0
2014-04-04 20:09:07 PDT-4723---[] LOG: last completed transaction was at log time 2014-04-04 16:11:12.264512-07
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000001000000000000002B" from archive
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000002.history" from archive
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000003.history" from archive
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000004.history" from archive
cp: cannot stat `/opt/PostgreSQL/9.3/archives/00000005.history': No such file or directory
2014-04-04 20:09:07 PDT-4723---[] LOG: selected new timeline ID: 5
cp: cannot stat `/opt/PostgreSQL/9.3/archives/00000001.history': No such file or directory
2014-04-04 20:09:07 PDT-4723---[] LOG: archive recovery complete
2014-04-04 20:09:08 PDT-4721---[] LOG: database system is ready to accept connections
2014-04-04 20:09:08 PDT-4764---[] LOG: autovacuum launcher started

-bash-4.1$ psql -c "select count(*),pg_is_in_recovery() from demo;"
count | pg_is_in_recovery
---------+-------------------
4000000 | f
(1 row)

Jejda, co se stalo, proč se nezastavil a na co si stěžuje?. Mějte na paměti, že pokud nejsou v době recovery_target_time přítomny žádné archivy WAL, pak se to nepozastaví a neočekává, jak to dospělo do posledního bodu a neotevře databázi pro ČTENÍ/ZÁPIS. V protokolech se bez většího natahování hledal soubor „00000001000000000000002C“, který není dostupný, protože v té době došlo k havárii clusteru. Někteří možná toto chování neuznávají, ale jeho skutečnost a dává smysl, když nejsou přítomny žádné archivy WAL, není důvod k pozastavení obnovy. Pokud je vůbec nutné pozastavit se i po žádných archivech WAL, pak použijte standby_mode=’on’ (HOT_STANDBY), v této metodě to nevyjde z obnovy, ale počká na archivy WAL.

Doufám, že to bylo užitečné.


  1. Vrácení oprávnění sloupců z propojeného serveru v SQL Server (příklady T-SQL)

  2. Použití poddotazu v příkazu Check v Oracle

  3. Architektura pro bezpečnost:Průvodce pro MySQL

  4. Chyba 1033 přijala přihlášení do pohotovostního režimu