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

Použití PostgreSQL Logical Replication k udržení vždy aktuálního testovacího serveru pro čtení/zápis

V tomto příspěvku na blogu budeme hovořit o logické replikaci v PostgreSQL:její případy použití, obecné informace o stavu této technologie a speciální případ použití, zejména o tom, jak nastavit předplatitelský (replikovaný) uzel primárního serveru v pořadí. fungovat jako databázový server pro testovací prostředí a splnit výzvy.

Úvod

Logická replikace, oficiálně představená v PostgreSQL 10, je nejnovější replikační technologie nabízená komunitou PostgreSQL. Logická replikace je pokračováním dědictví fyzické replikace, se kterou sdílí spoustu nápadů a kódu. Logická replikace funguje jako fyzická replikace pomocí WAL k zaznamenání logických změn nezávisle na verzi nebo konkrétní architektuře. Komunita PostgreSQL ušla dlouhou cestu, aby byla schopna poskytovat logickou replikaci do jádra nabídky.

Typy replikace a historie replikace PostgreSQL

Typy replikace v databázích lze klasifikovat následovně:

  • Fyzická (AKA binární) replikace
    • Úroveň operačního systému (replikace vSphere)
    • Úroveň systému souborů (DRBD)
    • Úroveň databáze (na základě WAL)
  • Logická replikace (úroveň databáze)
    • Na základě spouštěče (DBMirror, Slony)
    • Middleware (pgpool)
    • Na základě WAL (pglogická, logická replikace)

Plán, který přináší dnešní logickou replikaci založenou na WAL, byl:

  • 2001:DBMirror (založené na spouštěči)
  • 2004:Slony1 (založené na spouštěči), pgpool (middleware)
  • 2005:PITR (založený na WAL) představen v PostgreSQL 8.0
  • 2006:Teplý pohotovostní režim v PostgreSQL 8.2
  • 2010:Replikace fyzického streamování, pohotovostní režim v PostgreSQL 9.0
  • 2011:Replikace synchronního streamování v PostgreSQL 9.1
  • 2012:Kaskádová replikace streamování v PostgreSQL 9.2
  • 2013:Pracovníci na pozadí v PostgreSQL 9.3
  • 2014:Logické dekódovací API, replikační sloty. (Základy logické replikace) v PostgreSQL 9.4
  • 2015:2ndQuadrant představuje pglogic, předchůdce nebo logickou replikaci
  • 2017:Logická replikace v základním PostgreSQL 10!

Jak vidíme, mnoho technologií spolupracovalo, aby se logická replikace stala realitou:archivace WAL, teplé/horké pohotovostní režimy, fyzická replikace WAL, pracovníci na pozadí, logické dekódování. Za předpokladu, že čtenář zná většinu pojmů fyzické replikace, budeme hovořit o základních komponentách logické replikace.

Základní koncepty logické replikace PostgreSQL

Nějaká terminologie:

  • Publikace: Sada změn ze sady tabulek definovaných v konkrétní databázi na primárním serveru fyzické replikace. Publikace může zpracovávat všechny nebo některé z následujících položek:INSERT, DELETE, UPDATE, TRUNCATE.
  • Uzel majitele stránek: Server, na kterém je publikace umístěna.
  • Identita repliky: Způsob, jak identifikovat řádek na straně odběratele pro UPDATES a DELETE.
  • Předplatné: Připojení k uzlu vydavatele a jedné nebo více publikacím v něm. Předplatné používá vyhrazený replikační slot na vydavateli pro replikaci. Pro počáteční krok synchronizace lze použít další replikační sloty.
  • Uzel předplatitele: Server, na kterém se předplatné nachází.

Logická replikace se řídí modelem publikování/odběru. Jeden nebo více předplatitelů se může přihlásit k odběru jedné nebo více publikací v uzlu vydavatele. Předplatitelé mohou znovu publikovat, aby umožnili kaskádovou replikaci. Logická replikace tabulky se skládá ze dvou fází:

  • Pořízení snímku tabulky na vydavateli a jeho zkopírování odběrateli
  • Použití všech změn (od snímku) ve stejném pořadí

Logická replikace je transakční a zaručuje, že pořadí změn aplikovaných na odběratele zůstane stejné jako u vydavatele. Logická replikace poskytuje mnohem více svobody než fyzická (binární) replikace, proto ji lze použít více způsoby:

  • Replikace pro jednu databázi nebo tabulku (není třeba replikovat celý cluster)
  • Nastavení spouštěčů pro odběratele pro konkrétní úkol (jako je anonymizace, což je po vstupu GDPR v platnost docela horké téma)
  • Uzel odběratele shromažďuje data z mnoha uzlů vydavatelů, což umožňuje centrální analytické zpracování
  • Replikace mezi různými verzemi/architekturami/platformami (nulové prostoje upgradů)
  • Použití účastnického uzlu jako databázového serveru pro testovací/vývojové prostředí. Proč to chceme, je to, že testování se skutečnými daty je nejrealističtější typ testů.

Upozornění a omezení

Při používání logické replikace musíme mít na paměti určité věci. Některé z nich mohou ovlivnit některá rozhodnutí o návrhu, ale jiné mohou vést ke kritickým incidentům.

Omezení

  • Podporovány jsou pouze operace DML. Žádné DDL. Schéma musí být definováno předem
  • Sekvence se nereplikují
  • Velké objekty se nereplikují
  • Jsou podporovány pouze jednoduché základní tabulky (materializované pohledy, kořenové tabulky oddílů, cizí tabulky nejsou podporovány)

Upozornění

Základní problém, kterému dříve nebo později budeme muset čelit při používání logické replikace, jsou konflikty na předplatiteli. Předplatitel je normální server pro čtení/zápis, který může fungovat jako primární v nastavení fyzické replikace nebo dokonce jako vydavatel v nastavení kaskádové logické replikace. Dokud jsou prováděny zápisy do předplacených tabulek, může docházet ke konfliktům . Ke konfliktu dochází, když replikovaná data poruší omezení v tabulce, na kterou jsou aplikována. Obvykle je to operace INSERT, DELEES nebo UPDATES, které nemají žádný účinek, protože chybějící řádky nezpůsobí konflikt. Když dojde ke konfliktu, replikace se zastaví. Pracovník logického pozadí bude restartován v zadaném intervalu (interval wal_retrieve_retry_interval), avšak replikace se znovu nezdaří, dokud nebude vyřešena příčina konfliktu. Jde o kritický stav, který je nutné okamžitě řešit. Pokud tak neučiníte, replikační slot se zasekne na své aktuální pozici začne uzel vydavatele shromažďovat WAL a nevyhnutelně uzlu vydavatele dojde místo na disku . Konflikt je nejčastějším důvodem, proč se replikace může zastavit, ale jakýkoli jiný chybný stav bude mít stejný účinek:např. přidali jsme nový sloupec NOT NULL do předplacené tabulky, ale zapomněli jsme definovat výchozí hodnotu, nebo přidali sloupec do publikované tabulky, ale zapomněli jsme jej definovat v předplacené tabulce, nebo jsme udělali chybu v jeho typu a dva typy nejsou kompatibilní. Všechny tyto chyby zastaví replikaci. Existují dva způsoby, jak vyřešit konflikt:

  1. Vyřešte skutečný problém
  2. Přeskočte neúspěšnou transakci voláním pg_replication_origin_advance

Řešení b. jak je zde také ukázáno, může být nebezpečné a složité, protože jde v podstatě o proces pokusu a omylu, a pokud si někdo vybere aktuální LSN na vydavateli, může snadno skončit s nefunkčním replikačním systémem, protože mezi problematickými LSN mohou probíhat operace. a aktuální LSN, které bychom chtěli zachovat. Nejlepším způsobem je tedy skutečně vyřešit problém na straně předplatitele. Např. pokud dojde k porušení UNIQUE KEY, můžeme aktualizovat údaje o předplatiteli nebo jen smazat řádek. V produkčním prostředí musí být toto vše automatizované nebo alespoň částečně automatizované.

Nastavení uzlů vydavatele a předplatitele

Pro obecný přehled logické replikace v praxi si prosím přečtěte tento blog.

Relevantní parametry pro logickou replikaci jsou:

  • Strana vydavatele
    • wal_level>=„logický“
    • max_replication_slots>=#subscriptions + počáteční synchronizace tabulky
    • max_wal_senders>=max_replication_slots + other_physical_standbys
  • Strana předplatitele
    • max_replication_slots>=#subscriptions
    • max_logical_replication_workers>=#subscriptions + počáteční synchronizace tabulky
    • max_worker_processes>=max_logical_replication_workers + 1 + max_parallel_workers

Zaměříme se na speciální úvahy, které vyplývají z našeho speciálního účelu, k jehož dosažení potřebujeme logickou replikaci:vytvoření testovacího databázového clusteru pro použití testovacím oddělením . Publikaci lze definovat buď pro všechny tabulky, nebo tabulku po tabulce. Navrhuji přístup tabulky po tabulce, protože nám poskytuje maximální flexibilitu. Obecné kroky lze shrnout následovně:

  • Proveďte novou initdb v uzlu odběratele
  • Vypište schéma clusteru vydavatelů a zkopírujte jej do uzlu odběratele
  • Vytvořte schéma na odběrateli
  • Rozhodněte se, které stoly potřebujete a které ne.

Pokud jde o výše uvedenou odrážku, existují dva důvody, proč možná nepotřebujete replikaci tabulky nebo nastavení pro replikaci:

  • Je to fiktivní tabulka bez významu (a možná byste ji měli také vypustit z výroby)
  • je tabulka lokální pro produkční prostředí, což znamená, že dává dokonalý smysl, aby stejná tabulka v testovacím (předplatitelském) prostředí měla svá vlastní data

Všechny tabulky, které se účastní logické replikace, musí mít REPLICA IDENTITY. Toto je ve výchozím nastavení PRIMÁRNÍ KLÍČ, a pokud není k dispozici, lze definovat UNIKÁTNÍ klíč. Další krok k nalezení stavu tabulek s ohledem na REPLICA IDENTITY.

  • Najděte tabulky bez zjevného kandidáta na IDENTITU REPLICE
    select table_schema||'.'||table_name from information_schema.tables where table_type='BASE TABLE' AND table_schema||'.'||table_name NOT IN (select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type in ('PRIMARY KEY','UNIQUE')) AND table_schema NOT IN ('information_schema','pg_catalog') ;
  • Najděte tabulky bez PRIMÁRNÍHO KLÍČE, ale s UNIKÁTNÍM INDEXEM
    select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type = 'UNIQUE' EXCEPT select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type = 'PRIMARY KEY';
  • Projděte si výše uvedené seznamy a rozhodněte se, co s jednotlivými tabulkami uděláte
  • Vytvořte publikaci s tabulkami, pro které existuje PK
    select 'CREATE PUBLICATION data_for_testdb_pub FOR TABLE ONLY ' || string_agg(qry.tblname,', ONLY ') FROM (select table_schema||'.'||quote_ident(table_name) as tblname from information_schema.tables where table_type='BASE TABLE' AND table_schema||'.'||table_name IN (select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type in ('PRIMARY KEY')) AND table_schema NOT IN( 'information_schema','pg_catalog')  ORDER BY 1) as qry;
    \gexec
  • Potom vytvořte předplatné v uzlu předplatitele
    create subscription data_for_testdb_pub CONNECTION 'dbname=yourdb host=yourdbhost user=repmgr' PUBLICATION data_for_testdb_pub ;
    Výše uvedené zkopíruje také data.
  • Přidejte požadované tabulky, které mají UNIKÁTNÍ index
    Spouštějte v uzlech vydavatele i odběratele, např.:
    ALTER TABLE someschema.yourtable REPLICA IDENTITY USING INDEX yourindex_ukey;
    U vydavatele:
    ALTER PUBLICATION data_for_testdb_pub ADD TABLE ONLY someschema.yourtable;
    Na předplatiteli:
    ALTER SUBSCRIPTION data_for_testdb_pub REFRESH PUBLICATION WITH ( COPY_DATA );
  • V tomto okamžiku (synchronizace) byste měli vždy sledovat protokol PostgreSQL na uzlu odběratele. Nechcete žádné chyby nebo cokoliv (timeout), které brání pokračování logické replikace. VŠICHNI CHYBU OKAMŽITĚ ŘEŠTE nebo vydavatel bude nadále shromažďovat soubory WAL v pg_wal a nakonec mu dojde místo. Takže se musíte vypořádat s
    • Všechny CHYBY nebo jakékoli zprávy týkající se logického pracovníka, které vedou k ukončení
    • Postarejte se také o
      • wal_receiver_timeout
      • wal_sender_timeout

Po vyřešení všech problémů byste měli mít váš předplatitelský uzel šťastně spuštěný. Další otázkou tedy je, jak to použít jako testovací databázový server. Budete se muset vypořádat s těmito problémy/problémy:

  1. Anonymizace
  2. Primární klíče a jedinečné klíče, které jsou založeny na porušení sekvencí
  3. Obecný soubor osvědčených postupů
  4. Monitorování

Anonymizace

Pokud jde o anonymizaci osobních údajů, která je v EU vynucována GDPR, měli byste VŽDY napsat nějaké spouštěče, které vyprázdní všechna pole týkající se adres, bankovních účtů, rodinného stavu, telefonních čísel, e-mailů atd. Měli byste se poradit se svým bezpečnostním pracovníkem ve vaší společnosti co si ponechat a co vymazat. Spouštěče by měly být definovány jako ALWAYS, protože logický pracovník spouští příkazy jako REPLICA.

Primární klíče se sekvencemi

Co se týče sekvencí, je jasné, že s těmito klávesami bude problém, pokud se nevyřeší před zahájením jakéhokoli testu. Zvažte tento případ:

  • V pátek odpoledne provedete několik testů v databázi odběratelů vložením nového řádku do nějaké tabulky. Toto bude mít jako ID další hodnotu vygenerovanou sekvencí.
  • Na víkend jedete domů.
  • Některý produkční uživatel zadá řádek do stejné tabulky v databázi vydavatelů.
  • Řádek bude replikován na základě IDENTITY REPLIKA do uzlu odběratele, ale selže z důvodu narušení PK ERROR. Logický pracovník na pozadí se ukončí a zkusí to znovu. Ale bude selhat, dokud problém přetrvá.
  • Replikace se zasekne. Replikační slot začne hromadit WAL.
  • Vydavateli dochází místo na disku.
  • O víkendu dostanete e-mail, že váš primární uzel zpanikařil!

Chcete-li tedy vyřešit problém sekvence, můžete použít následující přístup:

select 'SELECT setval(''' || seqrelid::regclass||''','||CASE WHEN seqincrement <0 THEN -214748364 ELSE 214748364 END||');' from pg_sequence where seqtypid=20;
\gexec

Výše uvedené umožňuje nastavit sekvence na dostatečně velkou hodnotu, aby se v budoucnu nikdy nepřekrývaly v poměrně velkém okně, což vám umožní mít bezproblémový testovací server.

Soubor osvědčených postupů

Opravdu byste měli říct svým programátorům, aby jejich testy nebyly trvalé. Jakýkoli test po jeho dokončení by tedy měl ponechat databázi ve stejném stavu, v jakém byla před testem. S vkládáním ID na základě sekvence to není problém, dříve jsme viděli řešení. Ale u nesekvenčních (např. složených) UNIQUE klíčů to může být problém. Nejlepší je tedy tato testovací data smazat dříve, než se do předplacené tabulky dostane nějaký produkční řádek se stejnou hodnotou.

Zde bychom také měli přidat řešení změn schématu. Všechny změny schématu musí být provedeny také na předplatiteli, aby nedošlo k přerušení replikovaného provozu DML.

Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper

Monitorování

Opravdu byste měli investovat do dobrého monitorovacího řešení. Měli byste sledovat ...

U předplatitele:

  • VŠECHNY zprávy v protokolu odběratele, které jsou relevantní pro ukončení logického pracovníka. Instalace nástroje jako tail_n_mail s tím může opravdu pomoci. Konfigurace, o které je známo, že funguje:
    INCLUDE: ERROR:  .*publisher.*
    INCLUDE: ERROR:  .*exited with exit.*
    INCLUDE: LOG:  .*exited with exit.*
    INCLUDE: FATAL:  
    INCLUDE: PANIC:
    Jakmile obdržíme upozornění od tail_n_mail, měli bychom problém okamžitě vyřešit.
  • pg_stat_subscription. Pid by neměl být null. Také zpoždění by mělo být malé.

U vydavatele:

  • pg_stat_replication. To by mělo mít tolik řádků, kolik má být:Jeden pro každý připojený zálohovací režim replikace streamování (včetně účastnických uzlů a dalších fyzických pohotovostních režimů).
  • pg_replication_slots pro předplatitelský slot. Toto by mělo být aktivní.

Obecně to nějakou dobu trvá, než váš ideální testovací databázový server běží bez problémů, ale jakmile je všechny vyřešíte, vaši programátoři vám za to poděkují!


  1. Použití dotazu MySQL k procházení řádků k vytvoření rekurzivního stromu

  2. C#:Předá uživatelsky definovaný typ uložené proceduře Oracle

  3. Přírůstek identity skáče v databázi SQL Server

  4. SQL tabulka s položkou seznamu vs SQL tabulka s řádkem pro každou položku