db.dobo.sk

Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 06. Replikacie.

4 komentárov

Replikacie zabezpecuju:

  1. HA (high availability; vypadok jedneho serveru), alebo
  2. LB (load balancing; rozlozenie zataze)

Je mozne to implementovat roznymi sposobmi (tu je kompletny prehlad, ja sa zaoberam len 2 najcastejsimi sposobmi), vynikajuci prehlad moznych replikacnych topologii je uvedeny tu. Replikovat je mozne synchronne a asynchronne – je to vzdycky deal medzi konzistenciou dat a vykonom. Co znamena synchronny? Znamena konzistenciu dat medzi replikovanymi nodmi – v pripade synchronneho zapisu master vzdy caka na potvrdenie, ze slave data tiez zapisal a len potom ich zapise aj on sam na sebe. Vykonnostne sa samozrejme spotrebuva strojovy cas na “cakanie”.

                    +---------------------------------------------------+
                    |                                                   |
                    |             Replication in PostgreSQL             |
                    |                                                   |
                    +-+-----------------------------------------------+-+
                      |                                               |
                      |                                               |
              +-------v----+                                      +---v-------+
              |  Physical  |                                      |  Logical  |
              +-+---------++                                      +-----+-----+
                |         |                                             |
                |         |                                             |
+---------------v+       +v------------+                       +--------v--------+
|  Log Shipping  |       |  Streaming  |                       |     Logical     |
+----------------+       ++----------+-+                       |   Replication   |
                          |          |                         |      Slots      |
                          |          |                         +--------+--------+
                          |          |                                  |
                          |          |                                  |
              +-----------v---+   +--v--------------+          +--------v--------+
              |    Without    |   |  With Physical  |          |  Subscriptions  |
              |  Replication  |   |   Replication   |          +-----------------+
              |     Slots     |   |      Slots      |
              +---------------+   +-----------------+

U postgresu su dva zakladne typy replikacii: streaming replication (physical) a logical replication (via replication slots). Streaming (od verzie 9) je nazyvana aj fyzicka – replikuju sa fyzicky vsetky WAL logy a hlavnou nevyhodou je, ze sa musi replikovat uplne vsetko v ramci clusteru (neda sa ani samostatna databaza). Logical (pritomna od verzie 10) je trochu ina salka kavy – je vlatne rozparsovanie údajov vo wal logoch spat do SQL a to sa vyberovo posle na repliku (t.j. da sa to granulovat len na niektore objekty a zaznamy).

Existuje este oldschool replikacia archivovanim logov na repliku (Log shipping). Proste je v archive commandu primaru nadefinovany typicky rsync, ktory cele subory wal logov archivuje na repliku, ktora si ich prehraje. Nazyva sa to aj PITR (point-in-time-recovery). Vid komentare k prikladu validneho pouzitia.

Streaming replication

Je v principe posielanie zaznamov z WAL logov medzi primarom a standby serverom. Standby server (alebo viacej serverov) dohrava logy a udrzuje sa up to date s primarom po TCP koneksne. Na rozdiel od “log shippinu (PITR)” sa teda necaka na cely log, ale kazdy novy zaznam vo wal logu na primarnom clusteri sa posiela na standby. Standardne je to synchronna replikacia. Jak to funguje:

Na primare je spusteny proces walsender

Na standby su procesy dva – startup a walreceiver

Faza startup – startup nastartuje walreceiver, ktory sa snazi dosiahnut na primar. Pokial dosiahne a dostane odpoved, naviaze sa spojenie a walreceiver posle posledne LSN, ktore ma. Faza catch-up – Walsender si ho porovna so svojim LSN a pokial sa lisia, zacne dohravanie WAL logov tak, aby sa vyrovnali. Faza streaming –  ked sa LSN vyrovnaju a stanby “dobehol” primar, tak uz sa synchronne streamuju data, coz je rovnovazny a zelany stav. Specialna faza je faza backup, kde sa streamovanie pouziva pre ucely pg_basebackup. Tieto fazy sa daju zistit dotazom, ktory vylistuje databazy, v akom su stave:

SELECT * FROM pg_stat_replication;

Otazka: co sa stane, ak standby napriklad zbuchol, nejaku dobu nebezal a medzitym na primare vyexpirovali (odrotovali) nejake WAL logy? Odpoved: ste v pycy, toto je nevyhoda streaming replication, neda sa to dohrat do zelaneho stavu. Prave tento problem riesi logicka replikacia cez sloty. Ale tento problem vas hned palit nebude, pretoze, ked padne standby a replikacia je nastavena synchronne, tak primar ma tu blbu vlastnost, ze nedokonci transakcie a nepovoli nove (stale sa snazi dobuchat na standby server), coz je krajne neprijemne. Jedina ochrana proti tomu je v konfe vyprazdnit, alebo zakomentovat synchronous_standby_names = ” a znova nacitat konfiguraciu db servra.

Primar ma info o aktualnom diani na stanby serveroch, vie, v akom stave sa nachadzaju na nich WAL logy (su zapisane? flushnute? prehrate?) a to nasledovnym dotazom:

SELECT
application_name AS host,
write_location AS write_LSN,
flush_location AS flush_LSN,
replay_location AS replay_LSN
FROM pg_stat_replication;

Dobry clanok o streaming replication na SeveralNines je tu.

Zatialco systemovy view pg_stat_replication je zistovany na primare, na replike tuto ulohu plni pg_stat_wal_receiver. Nie su identicke, receiver pochopitelne nema tolko informacii, ako primar (nevie napr. nic o laggovani…).

Logical replication

Logicka replikacia, ako som spomenul, umoznuje replikovat medzi rozdielnymi verziami PG a hlavne umoznuje replikovat len casti clusteru (od DB az po jedinu tabulku). Ma rozne implementacie, najznamejsie 2 – “in-core logical replication“, coz je vbuildena vlastnost v Postgrese;  a pomocou externeho modulu pglogical od 3. strany (2nd quadrant).

Vlastnosti logickej replikacie:

  • LR je zalozene na modeli publication – subscriber. Master Postgres (publisher; CREATE PUBLICATION) publikuje vybrane data a Stanby node (subscriber; CREATE SUBSCRIPTION) ich konzumuje.
  • Publisher moze mat viac subscriberov a subscriber moze byt zaroven publisherom
  • Technicky to nie je az tak odlisne od streaming replikation – pracuje sa s WAL logmi, ktore su na strane publishera rozparsovane a je z nich posielana len ta informacia, ktora je nastavena vo filtroch pre publishing. V zasade parser rozparsuje informaciu vo WAL logoch na nejake pseudo SQL. Az toto je walsendrom posielane na target.
  • Technicky sa to deje cez replikacne sloty – Db objekty, ktore citaji WAL logy a posielaju informacie dalej. Az je informacia zkonzumovana subscriberom, WAL log je oznaceny ako zrely na rotovanie.
  • Pozor. LR nereplikuje DDL! T.j. schemy sa musia urobit rucne dopredu na subscriber DB. Taktiez je tam spusta obmedzeni, co sa tyka struktury DB objektov (napr. nazvy a typy columnov musia byt rovnake a pod.)…
  • Je zasadny rozdiel v praci medzi in-core replikaciou a pglogical. In-core sa ovlada vyhradne SQL syntaxou, pglogical volanim funkcii.

V dalsom ma bude zaujimat len pglogical, kde si urobim prehlad.

1. Pglogical je extension do postgresu, primarne na replikacie. Dokaze ale viac – aj tahat data z frontovych/message systemov typu RabbitMQ, Kafka a tak.

2. Vraj to na rozdiel od klasickej LR zvlada aj DDL.

3. Pozor, nezvlada to replikaciu medzi DBs s rozdielnym kodovanim. Ergo drz sa osvedceneho a vzdy pouzival UTF-8.

3. Vzhladom k tomu, ze to umoznuje replikovat medzi verziami 9-11, da sa to pouzit na upgrade (data sa odreplikuju na novsiu verziu)

4. V konfigu postgresu musi byt nastavene: wal_level = logical a max_replication_slots = ‘cislo’ (na publisheru i subscriberu) a je nutne nastavit aj workery.

5. Základny systemovy view pre prehlad logickej replikacie je pg_stat_subscription.

Kompletne o pglogical na webe autorov tu.

Replication lagging pri streaming replication – co robit, ked to laguje

Lagovanie medzi clustrami DB je celkom standardne neprijemna vec a moze mat celu radu pricin (od HW a sirky pasma az po konf databaze). Z uzivatelskeho hladiska nie je lagovanie nic ineho ako to, ze data na primare a replike sa lisia.

Pre posudenie toho, kde to viazne, su rozhodujuce 4 polozky v pg_stat_replication, ktore sa tykaju LSN. LSN ma tu dobru vlastnost, ze sa da vyjadrit binarne vo wal logu a tim stanovit, o kolko KB/MB/GB je replikacia posunuta:

  • sent_lsn – uvadza posledne LSN logu, ktore bolo poslane na repliku. Ak sa lisi od aktualneho LSN, tak to indikuje problemy so sietou (“nebolo mozne odoslat”)
  • write_lsn – indikuje posledne LSN, ktore sa zapisalo do pamatovych bufferov na replike. Ak sa lisi od aktualneho LSN na primare, tak to indikuje problem na sieti.
  • flush_lsn – posledne LSN, ktore bolo z pamate zapisane na persistent storage. Ak sa lisi od current LSN, tak problem s IOps? Vytazena storage?
  • replay_lsn – je posledne LSN, ktore bolo replikou prehrane tym je replikacia LSN ukoncena.

Replika potom posiela nejake info masteru o uspesnosti replikacia, to sa zapisuje do pg_stat_replication. Rozdiel medzi aktualnym LSN na masteru a replay_LSN na replike je total replication lag.

SELECT
client_addr AS client, usename AS user, application_name AS name,
state, sync_state AS mode,
(pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::bigint as pending,
(pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::bigint as write,
(pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::bigint as flush,
(pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::bigint as replay,
(pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::bigint / 1024 as total_lag
FROM pg_stat_replication;

Rychle porovnanie, ako sa lisia LSN na replike i s casovym udajom o poslednom replaynutom zazname:

SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_last_xact_replay_timestamp();

Pokial je stanby v recovery mode, tak:

SELECT pg_is_in_recovery(),pg_is_wal_replay_paused(), pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_last_xact_replay_timestamp();

píše: ďobo

December 5th, 2019 o 10:18 am

chlievik: postgresql

4 odpovedí to 'Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 06. Replikacie.'

Subscribe to comments with RSS or TrackBack to 'Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 06. Replikacie.'.

  1. Streaming repliku+archivaciu logov je vyhodne pouzivat pri failoveri 2 databaz na rozdielnych strojoch. Popis architektury:
    1. stroj A s postgresom, stroj B s postgresom
    2. Stroj A je primarny a poskytuje koneksny, B stroj je sekundarny a vyckava. V okamihu, ked padne stroj A, je mozne stroj B prepnut do aktivneo modu.
    3. Stroj A archivuje svoje logy scpckom do archivneho foldru stroja B. Stroj B zrkadlovo.
    4. Najdolezitejsia vec: stroj B je dlhodobo v recovery stavu z basebackupu. Akonahle je spusteny stroj A a archivueje logy do foldru na B, tak je z backupu recovery komandom aktivovany stroj B – ten prejde do recovery modu (recovery_target = now), ale nevybehne z neho, pretoze stale prichadzaju logy zo stroja A. Az ked sa stroj A nedajboze pojebe, tak recovery dobehne z posledneho wal logu na B a ten sa sam uvedie do provozuschopneho a aktualneho stavu.

    ďobo

    13 Dec 19 at 15:32

  2. ďobo

    2 Jan 20 at 9:57

  3. K prvej poznamke, HA prostrednictvom repliky: konfiguracia recovery.conf na stroji B:
    standby_mode = ‘on’
    primary_conninfo = ‘user=app_replication password=PASSWORD host=HOST-A port=5432’
    recovery_target_timeline = ‘latest’
    restore_command = ‘cp -f /var/lib/pgsql/rarchive/%f %p’ # z tejto lokality sosa archivovane wal logy z HOSTA-A
    archive_cleanup_command = ‘pg_archivecleanup -d /var/lib/pgsql/rarchive/ %r 2>>/var/lib/pgsql/cleanup.log’ #to je cistiaci komand pre archivovane logy, nech sa to dlhodobou prevadzkou nezaplni – logy zapisane do DB su “odcistene”

    dobo

    17 Feb 20 at 15:31

  4. log shipping – od ver. 8.2.
    streaming replication – od ver. 9.0
    synchronous streaming replication – od ver. 9.1.
    physical replication slots – od ver. 9.4.
    logical replication – od ver. 10

    ďobo

    8 Apr 20 at 9:05

okomentuj