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

PostgreSQL streamovací replikace – hluboký ponor

Znalost replikace je nutností pro každého, kdo spravuje databáze. Je to téma, které jste pravděpodobně viděli znovu a znovu, ale nikdy nezestárne. V tomto blogu se podíváme trochu na historii vestavěných replikačních funkcí PostgreSQL a hluboce se ponoříme do toho, jak funguje streamovaná replikace.

Když mluvíme o replikaci, budeme hodně mluvit o WAL. Pojďme si tedy rychle zopakovat něco o protokolech pro zápis napřed.

Write-Ahead Log (WAL)

Zápis napřed je standardní metodou pro zajištění integrity dat a ve výchozím nastavení je automaticky povolen.

WAL jsou protokoly REDO v PostgreSQL. Ale co přesně jsou protokoly REDO?

Protokoly REDO obsahují všechny změny provedené v databázi a používají se pro replikaci, obnovu, online zálohu a obnovu v určitém okamžiku (PITR). Jakékoli změny, které nebyly aplikovány na datové stránky, lze znovu provést z protokolů REDO.

Použití WAL má za následek výrazně snížený počet zápisů na disk, protože na disk je třeba vyprázdnit pouze soubor protokolu, aby bylo zaručeno, že transakce bude potvrzena, a nikoli každý datový soubor, který transakce změní.

Záznam WAL bude specifikovat změny provedené v datech, bit po bitu. Každý záznam WAL bude připojen do souboru WAL. Pozice vložení je číslo sekvence protokolu (LSN), bajtový posun v protokolech, který se zvyšuje s každým novým záznamem.

WAL jsou uloženy v adresáři pg_wal (nebo pg_xlog ve verzích PostgreSQL <10) v adresáři data. Tyto soubory mají výchozí velikost 16 MB (velikost můžete změnit změnou možnosti konfigurace --with-wal-segsize při sestavování serveru). Mají jedinečný přírůstkový název v následujícím formátu:"00000001 00000000 00000000".

Počet souborů WAL obsažených v pg_wal bude záviset na hodnotě přiřazené parametru checkpoint_segments (nebo min_wal_size a max_wal_size, v závislosti na verzi) v konfiguračním souboru postgresql.conf.

Jeden parametr, který musíte nastavit při konfiguraci všech instalací PostgreSQL, je wal_level. Úroveň wal_level určuje, kolik informací se zapisuje do WAL. Výchozí hodnota je minimální, která zapisuje pouze informace potřebné k obnově po havárii nebo okamžitém vypnutí. Archive přidává protokolování potřebné pro archivaci WAL; hot_standby dále přidává informace potřebné ke spouštění dotazů pouze pro čtení na záložním serveru; logical přidává informace nezbytné pro podporu logického dekódování. Tento parametr vyžaduje restart, takže pokud jste na to zapomněli, může být obtížné jej změnit při běžících produkčních databázích.

Další informace naleznete v oficiální dokumentaci zde nebo zde. Nyní, když jsme probrali WAL, pojďme se podívat na historii replikace v PostgreSQL.

Historie replikace v PostgreSQL

První metoda replikace (teplý pohotovostní režim), kterou PostgreSQL implementoval (verze 8.2, v roce 2006), byla založena na metodě odesílání protokolu.

To znamená, že záznamy WAL jsou přímo přesunuty z jednoho databázového serveru na druhý, aby byly použity. Dá se říci, že jde o spojitý PITR.

PostgreSQL implementuje odesílání protokolů na základě souborů přenosem záznamů WAL po jednom souboru (segmentu WAL).

Tato implementace replikace má nevýhodu:pokud dojde k závažnému selhání na primárních serverech, transakce, které ještě nebyly odeslány, budou ztraceny. Existuje tedy okno pro ztrátu dat (můžete to vyladit pomocí parametru archive_timeout, který lze nastavit až na několik sekund. Takto nízké nastavení však podstatně zvýší šířku pásma potřebnou pro odesílání souborů).

Tuto metodu odesílání protokolů založenou na souborech můžeme znázornit pomocí obrázku níže:

Doprava protokolů založených na souborech PostgreSQL

Poté ve verzi 9.0 (v roce 2010 ), byla zavedena streamovaná replikace.

Streamová replikace vám umožňuje zůstat aktuálnější, než je možné u odesílání protokolů založených na souborech. Funguje to tak, že se záznamy WAL (soubor WAL se skládá ze záznamů WAL) přenášejí za běhu (zasílání protokolů podle záznamů) mezi primárním serverem a jedním nebo několika záložními servery bez čekání na vyplnění souboru WAL.

V praxi se proces zvaný přijímač WAL, který běží na pohotovostním serveru, připojí k primárnímu serveru pomocí připojení TCP/IP. Na primárním serveru existuje další proces, nazvaný odesílatel WAL, a má na starosti odesílání registrů WAL na záložní server, jakmile k nim dojde.

Následující diagram představuje streamovanou replikaci:

PostgreSQL streamovací replikace

Při pohledu na výše uvedený diagram by vás mohlo zajímat, co se stane když selže komunikace mezi odesílatelem WAL a přijímačem WAL?

Při konfiguraci replikace streamování máte možnost povolit archivaci WAL.

Tento krok není povinný, ale je extrémně důležitý pro robustní nastavení replikace. Je nutné zabránit tomu, aby hlavní server recykloval staré soubory WAL, které ještě nebyly aplikovány na záložní server. Pokud k tomu dojde, budete muset repliku vytvořit znovu od začátku.

Při konfiguraci replikace s průběžnou archivací se začíná od zálohy. Chcete-li dosáhnout stavu synchronizace s primární, musí použít všechny změny hostované v WAL, ke kterým došlo po zálohování. Během tohoto procesu pohotovostní režim nejprve obnoví všechny dostupné WAL v umístění archivu (provede se voláním restore_command). Příkaz restore_command selže, když dosáhne posledního archivovaného záznamu WAL, takže poté se pohotovostní režim podívá do adresáře pg_wal, aby zjistil, zda tam změna existuje (toto funguje, aby se zabránilo ztrátě dat při selhání primárních serverů a některým změnám, které již byly přesunuty a použity na repliku, ještě nebyly archivovány).

Pokud se to nezdaří a požadovaný záznam zde neexistuje, začne komunikovat s primárním serverem prostřednictvím streamované replikace.

Kdykoli selže streamovací replikace, vrátí se ke kroku 1 a znovu obnoví záznamy z archivu. Tato smyčka opakování z archivu, pg_wal a prostřednictvím streamingové replikace pokračuje, dokud se server nezastaví nebo není spuštěno převzetí služeb při selhání spouštěcím souborem.

Následující diagram představuje konfiguraci streamované replikace s průběžnou archivací:

Streamovací replikace PostgreSQL s průběžnou archivací

Streamová replikace je ve výchozím nastavení asynchronní, takže na v kterémkoli daném okamžiku můžete mít některé transakce, které lze potvrdit primárnímu serveru a ještě nereplikovat na záložní server. To znamená určitou potenciální ztrátu dat.

Toto zpoždění mezi potvrzením a dopadem změn v replice má být skutečně malé (několik milisekund), samozřejmě za předpokladu, že replikační server je dostatečně výkonný, aby udržel krok s zatížení.

Pro případy, kdy ani riziko mírné ztráty dat není přijatelné, zavedla verze 9.1 funkci synchronní replikace.

Při synchronní replikaci každé potvrzení transakce zápisu čeká, dokud není přijato potvrzení, že potvrzení je zapsáno do protokolu pro zápis na disk primárního i záložního serveru.

Tato metoda minimalizuje možnost ztráty dat; aby k tomu došlo, budete potřebovat, aby primární i pohotovostní režim selhaly současně.

Zjevnou nevýhodou této konfigurace je, že doba odezvy pro každou transakci zápisu se prodlužuje, protože musí čekat, dokud všechny strany nezareagují. Čas pro potvrzení je tedy minimálně okružní cesta mezi primární a replikou. Transakce pouze pro čtení nebudou tímto ovlivněny.

Chcete-li nastavit synchronní replikaci, musíte zadat název_aplikace v primárním_conninfo obnovy pro každý záložní soubor server.conf:primary_conninfo ='...název_aplikace=pohotovostníX' .

Musíte také zadat seznam rezervních serverů, které se zúčastní synchronní replikace:synchronous_standby_name ='standbyX,standbyY'.

Můžete nastavit jeden nebo několik synchronních serverů a tento parametr také určuje, jakou metodu (FIRST a ANY) vybrat synchronní pohotovostní režimy z uvedených. Další informace o nastavení režimu synchronní replikace najdete na tomto blogu. Je také možné nastavit synchronní replikaci při nasazení prostřednictvím ClusterControl.

Poté, co replikaci nakonfigurujete a bude spuštěna, budete muset implementovat monitorování

Monitorování replikace PostgreSQL

Pohled pg_stat_replication na hlavním serveru obsahuje mnoho relevantních informací:

postgres=# SELECT * FROM pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 756
usesysid         | 16385
usename          | cmon_replication
application_name | pgsql_0_node_0
client_addr      | 10.10.10.137
client_hostname  |
client_port      | 36684
backend_start    | 2022-04-13 17:45:56.517518+00
backend_xmin     |
state            | streaming
sent_lsn         | 0/400001C0
write_lsn        | 0/400001C0
flush_lsn        | 0/400001C0
replay_lsn       | 0/400001C0
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2022-04-13 17:53:03.454864+00

Podívejme se na to podrobně:

  • pid:ID procesu walsender procesu.

  • usesysid:OID uživatele, které se používá pro streamování replikace.

  • usename:Jméno uživatele, který se používá pro streamování replikace.

  • název_aplikace:Název aplikace připojený k hlavnímu serveru.

  • client_addr:Adresa pohotovostní/streamovací replikace.

  • client_hostname:Název hostitele v pohotovostním režimu.

  • client_port:Číslo portu TCP, na kterém pohotovostní režim komunikuje s odesílatelem WAL.

  • backend_start:Čas zahájení, když se SR připojí k Primární.

  • stav:Aktuální stav odesílatele WAL, tj. streamování.

  • sent_lsn:Místo poslední transakce odesláno do pohotovostního režimu.

  • write_lsn:Poslední transakce zapsaná na disk v pohotovostním režimu.

  • flush_lsn:Poslední vyprázdnění transakce na disk v pohotovostním režimu.

  • replay_lsn:Poslední vyprázdnění transakce na disk v pohotovostním režimu.

  • sync_priority:Priorita pohotovostního serveru vybraného jako synchronní pohotovostní režim.

  • sync_state:Stav synchronizace v pohotovostním režimu (je asynchronní nebo synchronní).

Můžete také vidět procesy odesílatele/přijímače WAL běžící na serverech.

Odesílatel (primární uzel):

[[email protected] ~]# ps aux |grep postgres
postgres     727  0.0  2.2 917060 47936 ?        Ss   17:45   0:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
postgres     732  0.0  0.2 351904  5280 ?        Ss   17:45   0:00 postgres: 14/main: logger
postgres     734  0.0  0.5 917188 10560 ?        Ss   17:45   0:00 postgres: 14/main: checkpointer
postgres     735  0.0  0.4 917208  9908 ?        Ss   17:45   0:00 postgres: 14/main: background writer
postgres     736  0.0  1.0 917060 22928 ?        Ss   17:45   0:00 postgres: 14/main: walwriter
postgres     737  0.0  0.4 917748  9128 ?        Ss   17:45   0:00 postgres: 14/main: autovacuum launcher
postgres     738  0.0  0.3 917060  6320 ?        Ss   17:45   0:00 postgres: 14/main: archiver last was 00000001000000000000003F
postgres     739  0.0  0.2 354160  5340 ?        Ss   17:45   0:00 postgres: 14/main: stats collector
postgres     740  0.0  0.3 917632  6892 ?        Ss   17:45   0:00 postgres: 14/main: logical replication launcher
postgres     756  0.0  0.6 918252 13124 ?        Ss   17:45   0:00 postgres: 14/main: walsender cmon_replication 10.10.10.137(36684) streaming 0/400001C0

Přijímač (pohotovostní uzel):

[[email protected] ~]# ps aux |grep postgres
postgres     727  0.0  2.2 917060 47576 ?        Ss   17:45   0:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
postgres     732  0.0  0.2 351904  5396 ?        Ss   17:45   0:00 postgres: 14/main: logger
postgres     733  0.0  0.3 917196  6360 ?        Ss   17:45   0:00 postgres: 14/main: startup recovering 000000010000000000000040
postgres     734  0.0  0.4 917060 10056 ?        Ss   17:45   0:00 postgres: 14/main: checkpointer
postgres     735  0.0  0.3 917060  6304 ?        Ss   17:45   0:00 postgres: 14/main: background writer
postgres     736  0.0  0.2 354160  5456 ?        Ss   17:45   0:00 postgres: 14/main: stats collector
postgres     737  0.0  0.6 924532 12948 ?        Ss   17:45   0:00 postgres: 14/main: walreceiver streaming 0/400001C0

Jedním ze způsobů, jak zkontrolovat, jak je vaše replikace aktuální, je zkontrolovat množství záznamů WAL vygenerovaných na primárním serveru, ale dosud nepoužitých na záložním serveru.

Primární:

postgres=# SELECT pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 0/400001C0
(1 row)

Pohotovostní režim:

postgres=# SELECT pg_last_wal_receive_lsn();
 pg_last_wal_receive_lsn
-------------------------
 0/400001C0
(1 row)
postgres=# SELECT pg_last_wal_replay_lsn();
 pg_last_wal_replay_lsn
------------------------
 0/400001C0
(1 row)

K získání zpoždění v sekundách můžete použít následující dotaz v pohotovostním uzlu:

postgres=# SELECT CASE WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()
THEN 0
ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp())
END AS log_delay;
 log_delay
-----------
         0
(1 row)

A můžete také vidět poslední přijatou zprávu:

postgres=# SELECT status, last_msg_receipt_time FROM pg_stat_wal_receiver;
  status   |    last_msg_receipt_time
-----------+------------------------------
 streaming | 2022-04-13 18:32:39.83118+00
(1 row)

Monitorování replikace PostgreSQL pomocí ClusterControl

K monitorování vašeho PostgreSQL clusteru můžete použít ClusterControl, který vám umožní monitorovat a provádět několik dalších úloh správy, jako je nasazení, zálohování, škálování a další.

V sekci přehledu budete mít úplný obrázek o clusteru databáze aktuální stav. Chcete-li zobrazit další podrobnosti, můžete vstoupit do sekce řídicího panelu, kde uvidíte spoustu užitečných informací rozdělených do různých grafů.
 

V sekci topologie můžete vidět svou aktuální topologii v uživatelském přátelským způsobem a také můžete přes uzly provádět různé úkoly pomocí tlačítka Akce uzlu.

Streamová replikace je založena na odeslání záznamů WAL a jejich použití v pohotovostním režimu server, určuje, jaké bajty přidat nebo změnit v jakém souboru. V důsledku toho je záložní server ve skutečnosti bit po bitu kopie primárního serveru. Zde jsou však některá známá omezení:

  • Nelze replikovat do jiné verze nebo architektury.

  • Na pohotovostním serveru nelze nic měnit.

  • Nemáte příliš podrobné informace o tom, co replikujete.

Pro překonání těchto omezení přidal PostgreSQL 10 podporu pro logickou replikaci

Logická replikace

Logická replikace také použije informace v souboru WAL, ale dekóduje je do logických změn. Místo toho, aby věděl, který bajt se změnil, bude přesně vědět, jaká data byla vložena do které tabulky.

Je založen na modelu „zveřejnit“ a „přihlásit se k odběru“, kdy jeden nebo více odběratelů odebírá jednu nebo více publikací v uzlu vydavatele, který vypadá takto:

Logická replikace PostgreSQL

Zabalení

Díky streamovací replikaci můžete neustále odesílat a používat záznamy WAL na své záložní servery, čímž zajistíte, že informace aktualizované na primárním serveru budou přeneseny na záložní server v reálném čase, což umožní oběma zůstat v synchronizaci .

ClusterControl zjednodušuje nastavení streamingové replikace a můžete ji zdarma hodnotit po dobu 30 dnů.

Pokud se chcete dozvědět více o logické replikaci v PostgreSQL, nezapomeňte si prohlédnout tento přehled logické replikace a tento příspěvek o doporučených postupech replikace PostgreSQL.

Chcete-li získat další tipy a osvědčené postupy pro správu vaší databáze s otevřeným zdrojovým kódem, sledujte nás na Twitteru a LinkedIn a přihlaste se k odběru našeho newsletteru pro pravidelné aktualizace.


  1. Jak to_char() funguje v PostgreSQL

  2. Aktualizace tabulky v Oracle, pokud je nějaká hodnota pole nulová a určení, zda je aktualizace úspěšná

  3. Jak Floor() funguje v PostgreSQL

  4. Proč (a jak) rozdělit sloupec pomocí master..spt_values?