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

Použití replikačních slotů PostgreSQL

Co jsou replikační sloty?

V dobách, kdy ještě nebyly zavedeny „Replikační sloty“, byla správa segmentů WAL výzvou. Při standardní streamovací replikaci master nemá žádnou znalost stavu slave. Vezměte si příklad mastera, který provádí velkou transakci, zatímco pohotovostní uzel je několik hodin v režimu údržby (jako je aktualizace systémových balíčků, úprava zabezpečení sítě, upgrade hardwaru atd.). V určitém okamžiku master odebere svůj transakční protokol (segmenty WAL) při průchodu kontrolním bodem. Jakmile je slave mimo údržbu, může mít velké zpoždění slave a musí dohnat pána. Nakonec otrok dostane fatální problém, jako je níže:

LOG:  started streaming WAL from primary at 0/73000000 on timeline 1

FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000000000073 has already been removed

Typickým přístupem je specifikovat v postgresql.conf archivační skript WAL, který zkopíruje soubory WAL do jednoho nebo více umístění dlouhodobého archivu. Pokud nemáte žádné pohotovostní režimy nebo jiné klienty pro streamování replikace, pak může server v zásadě zahodit soubor WAL, jakmile je archivační skript hotový nebo odpoví OK. Stále však budete potřebovat nějaké nedávné soubory WAL pro obnovu po havárii (data z posledních souborů WAL se během obnovy po havárii přehrají. V našem příkladu pohotovostního uzlu, který je umístěn na dlouhou dobu údržby, nastanou problémy, když se vrátí online a požádá primární pro soubor WAL, který primární již nemá, pak replikace selže.

Tento problém byl vyřešen v PostgreSQL 9.4 prostřednictvím "Replication Slots".

Pokud nepoužíváte replikační sloty, běžným způsobem, jak snížit riziko selhání replikace, je nastavit wal_keep_segments dostatečně vysoko, aby se soubory WAL, které by mohly být potřeba, netočily nebo recyklovaly. Nevýhodou tohoto přístupu je, že je těžké určit, jaká hodnota je pro vaše nastavení nejlepší. Nebudete potřebovat každodenní údržbu nebo nebudete muset uchovávat velkou hromadu souborů WAL, které zabírají vaše diskové úložiště. I když to funguje, není to ideální řešení, protože riskování místa na disku na hlavním serveru může způsobit selhání příchozích transakcí.

Alternativním přístupem, jak nepoužívat replikační sloty, je nakonfigurovat PostgreSQL s nepřetržitou archivací a poskytnout příkaz restore_command, který umožní replice přístup k archivu. Abyste zabránili hromadění WAL na primárním místě, můžete pro soubory WAL použít samostatný svazek nebo úložné zařízení, např. SAN nebo NFS. Další věcí je synchronní replikace, protože ta vyžaduje, aby primární musel čekat na pohotovostní uzly k potvrzení transakce. To znamená, že zajišťuje, že soubory WAL byly aplikovány na pohotovostní uzly. Ale přesto je nejlepší, když poskytujete archivační příkazy z primární, takže jakmile budou WAL recyklovány v primární, můžete si být jisti, že máte zálohy WAL pro případ obnovy. I když v některých situacích není synchronní replikace ideálním řešením, protože ve srovnání s asynchronní replikací přináší určitou režii na výkon.

Typy replikačních slotů

Existují dva typy replikačních slotů. Jsou to:

Sloty fyzické replikace 

Lze použít pro standardní streamovací replikaci. Zajistí, aby data nebyla recyklována příliš brzy.

Logické replikační sloty

Logická replikace dělá to samé jako fyzické replikační sloty a používá se pro logickou replikaci. Používají se však pro logické dekódování. Myšlenkou logického dekódování je dát uživatelům možnost připojit se k protokolu transakcí a dekódovat jej pomocí pluginu. Umožňuje extrahovat změny provedené v databázi a tím i v transakčním protokolu v jakémkoli formátu a pro jakýkoli účel.

V tomto blogu budeme používat fyzické replikační sloty a jak toho dosáhnout pomocí ClusterControl.

Výhody a nevýhody použití replikačních slotů

Sloty pro replikace jsou po aktivaci rozhodně přínosné. Ve výchozím nastavení nejsou „Replikační sloty“ povoleny a je třeba je nastavit ručně. Mezi výhody použití replikačních slotů patří

  • Zajišťuje, že hlavní server uchová dostatek segmentů WAL, aby je všechny repliky mohly přijmout
  • Brání hlavnímu serveru v odebrání řádků, které by mohly způsobit konflikt obnovy u replik
  • Hlavní server může protokol transakcí recyklovat až poté, co jej spotřebují všechny repliky. Výhodou zde je, že otrok nikdy nemůže zaostávat natolik, že by bylo potřeba znovu synchronizovat.

Replikační sloty také přicházejí s určitými výhradami.

  • Slot pro osiřelou replikaci může způsobit neomezený růst disku kvůli nahromadění souborů WAL z hlavního serveru
  • Podřízené uzly umístěné pod dlouhou údržbou (například dny nebo týdny) a spojené s replikačním slotem budou mít neomezený růst disku kvůli nahromadění souborů WAL z hlavního serveru

Můžete to sledovat dotazem na pg_replication_slots a určit sloty, které se nepoužívají. Na to se ještě podíváme o něco později.

Použití replikačních slotů 

Jak bylo uvedeno dříve, existují dva typy replikačních slotů. Pro tento blog použijeme fyzické replikační sloty pro streamovanou replikaci.

Vytvoření replikačního slotu

Vytvoření replikace je jednoduché. Chcete-li to provést, musíte vyvolat existující funkci pg_create_physical_replication_slot a musí být spuštěna a vytvořena v hlavním uzlu. Funkce je jednoduchá,

maximus_db=# \df pg_create_physical_replication_slot

Schema              | pg_catalog

Name                | pg_create_physical_replication_slot

Result data type    | record

Argument data types | slot_name name, immediately_reserve boolean DEFAULT false, OUT slot_name name, OUT xlog_position pg_lsn

Type                | normal

např. Vytvoření replikačního slotu s názvem slot1,

postgres=# SELECT pg_create_physical_replication_slot('slot1');

-[ RECORD 1 ]-----------------------+---------

pg_create_physical_replication_slot | (slot1,)

Názvy replikačních slotů a jejich základní konfigurace platí pouze pro celý systém, nikoli pro celý cluster. Například, pokud máte nodeA (aktuální hlavní) a pohotovostní uzly nodeB a nodeC, čímž vytváříte slot na hlavním uzlu A, jmenovitě "slot1", data nebudou dostupná pro nodeB a nodeC. Proto, když dojde k převzetí služeb při selhání/přepnutí, musíte znovu vytvořit sloty, které jste vytvořili.

Vypuštění replikačního slotu

Nepoužívané replikační sloty musí být zrušeny nebo odstraněny. Jak bylo uvedeno dříve, pokud existují osiřelé replikační sloty nebo sloty, které nebyly přiřazeny žádnému klientovi nebo pohotovostním uzlům, může to vést k neomezeným problémům s místem na disku, pokud je ponecháno bez vypuštění. Je tedy velmi důležité, aby je bylo nutné upustit, když se již nepoužívá. Chcete-li jej zahodit, jednoduše vyvolejte pg_drop_replication_slot. Tato funkce má následující definici:

maximus_db=# \df pg_drop_replication_slot

Schema              | pg_catalog

Name                | pg_drop_replication_slot

Result data type    | void

Argument data types | name

Type                | normal

Zrušení je jednoduché:

maximus_db=# select pg_drop_replication_slot('slot2');

-[ RECORD 1 ]------------+-

pg_drop_replication_slot |

Monitorování vašich replikačních slotů PostgreSQL

Sledování replikačních slotů je něco, co byste si neměli nechat ujít. Stačí shromáždit informace ze zobrazení pg_replication_slots v primárním/hlavním uzlu, jak je uvedeno níže:

postgres=# select * from pg_replication_slots;

-[ RECORD 1 ]-------+-----------

slot_name           | main_slot

plugin              |

slot_type           | physical

datoid              |

database            |

active              | t

active_pid          | 16297

xmin                |

catalog_xmin        |

restart_lsn         | 2/F4000108

confirmed_flush_lsn |

-[ RECORD 2 ]-------+-----------

slot_name           | main_slot2

plugin              |

slot_type           | physical

datoid              |

database            |

active              | f

active_pid          |

xmin                |

catalog_xmin        |

restart_lsn         |

confirmed_flush_lsn |

Výsledek výše ukazuje, že byl obsazen hlavní_slot, ale nikoli hlavní_slot2.

Další věc, kterou můžete udělat, je sledovat, jak velké zpoždění za sloty máte. Chcete-li toho dosáhnout, můžete jednoduše použít dotaz založený na ukázkovém výsledku níže:

postgres=# SELECT redo_lsn, slot_name,restart_lsn, 

round((redo_lsn-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

redo_lsn    | slot_name | restart_lsn | gb_behind 

------------+-----------+-------------+-----------

 1/8D400238 |     slot1 | 0/9A000000 | 3.80

Ale redo_lsn není v 9.6 přítomen, měl by používat redo_location, takže v 9.6

imbd=# SELECT redo_location, slot_name,restart_lsn, 

round((redo_location-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

-[ RECORD 1 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

-[ RECORD 2 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot2

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

Požadavky na systémové proměnné

Implementace replikačních slotů vyžaduje ruční nastavení. Existují proměnné, které musíte mít na paměti, které vyžadují změny a jsou specifikovány ve vašem postgresql.conf. Viz níže:

  • max_replication_slots – Pokud je nastaveno na 0, znamená to, že replikační sloty jsou zcela zakázány. Pokud používáte PostgreSQL <10 verzí, tento slot musí být specifikován jinak než 0 (výchozí). Od PostgreSQL 10 je výchozí hodnota 10. Tato proměnná určuje maximální počet replikačních slotů. Nastavení na nižší hodnotu, než je počet aktuálně existujících replikačních slotů, zabrání spuštění serveru.
  • wal_level – musí být alespoň replika nebo vyšší (replika je výchozí). Nastavení hot_standby nebo archiv se namapuje na repliku. Pro fyzický replikační slot stačí replika. Pro sloty logické replikace je upřednostňován logický.
  • max_wal_senders – ve výchozím nastavení nastaveno na 10, 0 ve verzi 9.6, což znamená, že replikace je zakázána. Doporučujeme, abyste toto nastavení nastavili alespoň na 16, zejména pokud používáte ClusterControl.
  • horký_pohotovostní režim – ve verzích <10 je třeba tuto možnost nastavit na hodnotu on, která je ve výchozím nastavení vypnutá. To je důležité pro pohotovostní uzly, což znamená, že když jsou zapnuté, můžete se připojit a spouštět dotazy během obnovy nebo v pohotovostním režimu.
  • primary_slot_name – tato proměnná se nastavuje pomocí recovery.conf v pohotovostním uzlu. Toto je slot, který použije přijímač nebo pohotovostní uzel při připojení k odesílateli (nebo primárnímu/masteru).

Musíte si uvědomit, že tyto proměnné většinou vyžadují restart databázové služby, aby bylo možné znovu načíst nové hodnoty.

Použití replikačních slotů v prostředí ClusterControl PostgreSQL

Nyní se podíváme, jak můžeme použít fyzické replikační sloty a implementovat je v nastavení Postgres spravovaném ClusterControl.

Nasazení uzlů databáze PostgreSQL

Začněme nasazovat 3-uzlový PostgreSQL Cluster pomocí ClusterControl tentokrát s verzí PostgreSQL 9.6.

ClusterControl nasadí uzly s následujícími systémovými proměnnými definovanými odpovídajícím způsobem na základě jejich výchozích hodnot nebo vyladěné hodnoty. V:

postgres=# select name, setting from pg_settings where name in ('max_replication_slots', 'wal_level', 'max_wal_senders', 'hot_standby');

         name          | setting 

-----------------------+---------

 hot_standby           | on

 max_replication_slots | 0

 max_wal_senders       | 16

 wal_level             | replica

(4 rows)

Ve verzích PostgreSQL> 9.6 je výchozí hodnota max_replication_slots 10, což je ve výchozím nastavení povoleno, ale ne ve verzích 9.6 nebo nižších, které jsou ve výchozím nastavení zakázány. Musíte přiřadit max_replication_slots vyšší než 0. V tomto příkladu jsem nastavil max_replication_slots na 5.

[email protected]:~# grep 'max_replication_slots' /etc/postgresql/9.6/main/postgresql.conf 

# max_replication_slots = 0                     # max number of replication slots

max_replication_slots = 5

a restartoval službu,

[email protected]:~# pg_lsclusters 

Ver Cluster Port Status Owner    Data directory Log file

9.6 main    5432 online postgres /var/lib/postgresql/9.6/main pg_log/postgresql-%Y-%m-%d_%H%M%S.log



[email protected]:~# pg_ctlcluster 9.6 main restart

Nastavení replikačních slotů pro primární a pohotovostní uzly

V ClusterControl neexistuje žádná možnost, jak to udělat, takže musíte své sloty vytvořit ručně. V tomto příkladu jsem vytvořil sloty v primárním hostiteli 192.168.30.100:

192.168.10.100:5432 [email protected]_db=# SELECT pg_create_physical_replication_slot('slot1'), pg_create_physical_replication_slot('slot2');

 pg_create_physical_replication_slot | pg_create_physical_replication_slot 

-------------------------------------+-------------------------------------

 (slot1,)                            | (slot2,)

(1 row)

Kontrola toho, co jsme právě vytvořili, ukazuje,

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | f      | | |       | | 

 slot2     | | physical  | | | f      | | |       | | 

(2 rows)

Nyní v pohotovostních uzlech musíme aktualizovat soubor recovery.conf a přidat proměnnou primární_název_slotu a změnit název_aplikace, aby bylo snazší identifikovat uzel. Takto to vypadá v hostiteli 192.168.30.110 recovery.conf: 

[email protected]:/var/lib/postgresql/9.6/main/pg_log# cat ../recovery.conf 

standby_mode = 'on'

primary_conninfo = 'application_name=node11 host=192.168.30.100 port=5432 user=cmon_replication password=m8rLmZxyn23Lc2Rk'

recovery_target_timeline = 'latest'

primary_slot_name = 'slot1'

trigger_file = '/tmp/failover_5432.trigger'

Totéž dělá také v hostiteli 192.168.30.120, ale změnil název_aplikace a nastavil primární_název_slotu ='slot2'.

Kontrola stavu replikačního slotu:

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | t      | 24252 | |       | 0/CF0A4218 | 

 slot2     | | physical  | | | t      | 11635 | |       | 0/CF0A4218 | 

(2 rows)

Co ještě potřebujete?

Protože ClusterControl v tuto chvíli nepodporuje replikační sloty, je třeba vzít v úvahu některé věci. co to je? Pojďme do detailů.

Proces převzetí služeb při selhání/přepnutí

Při pokusu o automatické převzetí služeb při selhání nebo přepnutí prostřednictvím ClusterControl nebudou sloty zachovány z primárních a pohotovostních uzlů. Musíte to znovu vytvořit ručně, zkontrolovat proměnné, zda jsou nastaveny správně, a podle toho upravit soubor recovery.conf.

Přestavba Slave z Master

Při přestavbě slave nebude soubor recovery.conf zachován. To znamená, že vaše nastavení recovery.conf s názvem primárního_slotu budou vymazána. Musíte to zadat znovu ručně a zkontrolovat pohled pg_replication_slots, abyste zjistili, zda jsou sloty správně použity nebo zda zůstaly osiřelé.

Pokud chcete znovu sestavit podřízený/pohotovostní uzel z hlavního, možná budete muset zvážit zadání proměnné env PGAPPNAME stejně jako příkaz níže:

$ export PGAPPNAME="app_repl_testnode15"; /usr/pgsql-9.6/bin/pg_basebackup -h 192.168.10.190 -U cmon_replication -D /var/lib/pgsql/9.6/data -p5434 -W -S main_slot -X s -R -P

Zadání parametru -R je velmi důležité, takže znovu vytvoří soubor recovery.conf, zatímco -S určí název slotu, který se má použít při přestavbě pohotovostního uzlu.

Závěr

Implementace replikačních slotů v PostgreSQL je přímočará, přesto existují určitá upozornění, která si musíte zapamatovat. Při nasazování s ClusterControl budete muset aktualizovat některá nastavení během převzetí služeb při selhání nebo znovu sestavení slave zařízení.


  1. Odebrat identitu ze sloupce v tabulce

  2. Proč se výsledky z dotazu SQL nevracejí v očekávaném pořadí?

  3. 4 způsoby, jak získat seznam plánů v SQL Server Agent (T-SQL)

  4. Jak vypočítat medián v MySQL