Replikacja logiczna PostgreSQL (natywna)
Error rendering macro 'toc' : null
Zasady ogólne
Pojęcia
Publisher - ten node bazodanowy, z którego zmiany są pobierane i na którym tworzymy publikację.
Subscriber - ten node, który pobiera zmiany (tu tworzymy naturalnie subskrypcję). Nie mówimy w tym wypadku o slave, ponieważ nie jest to node tak zależny jak w wypadku replikacji binarnej.
Slot - mechanizm przekazywania zmian, miejsce komunikacji publishera i subscribera.
Jak to działa
Dokumentacja PostgreSQL jest jedną z najlepszych, pełny opis działania mechanizmu znajdziemy tutaj. W wersji bardzo skróconej:
Podczas tworzenia publikacji definiujemy jakie zmiany chcemy replikować (operacje + ); podczas tworzenia subskrypcji definiujemy z kolei skąd te zmiany pobierać (credentiale do bazy + nazwa publikacji), wówczas tworzy się również slot.
Proces walsender
Publisher przekazuje zmiany na slot w postaci binarnej, subscriber łączy się do slotu, pobiera zmiany i przetwarza je robiąc reverse engineering.
Jeśli w sybskrypcji nie zdefiniujemy inaczej, pierwszym krokiem będzie wykonanie inicjalnego snapshotu danych (proces utworzy osobny slot replikacji). Po zakończeniu snapshotu proces walsender rozpoczyna
Co można, a czego nie można z replikacją logiczną
Replikacja logiczną nie jest pełną replikacją master - master, chwilowo jeszcze w środowiskach produkcyjnych nie jest zalecany dwukierunkowy zapis.
Choć mechanizm slotów został wdrożony w wersji 9.4, replikacja logiczna w 10, sensowną dyskusję o natywnej replikacji zaczynamy z wersją 12.
Można:
replikować wybrane tabele;
replikować dowolną komendę:
instert
update
delete
truncate
dowolną kombinację powyższych
mieć:
dodatkowe niezreplikowane tabele na subscriberze;
dodatkowe kolumny w replikowanej tabeli po stronie
mieć różnych użytkowników po obu stronach
replikowane tabele:
obejmować różnymi dostępami, triggerami, widokami
inaczej indeksować na node'ach (np publishera optymalizujemy pod zapis, a subscribera pod odczyt)
łączyć replikację z innymi rozwiązaniami ze standardu SQL/MED (np. FDW)
replikować na wyższą wersję PostgreSQL (min. wersja pg na publisherze 9.4, min. wersja na subscriberze 10)
Nie można:
replikować tabel bez klucza głównego, gdy replikujemy update i delete
automatycznie replikować poleceń DDL
replikować tylko części kolumn, tzn. wszystkie kolumny z publishera muszą się znaleźć ma subcriberze
Ograniczenia
Sekewencje
Uwaga - patycje!
W przypadku baz i tabel partycjonowanych replikacja pozwala na partycje na subscriberze, ale dopiero w wersji 13.
Konfiguracja
Tworzymy dedykowanego dla replikacji użytkownika - po obu stronach:
CREATE USER pglogical WITH SUPERUSER REPLICATION;Dodajemy wpis w pg_hba.conf po stronie publisher
'LOG_REP_1': type: 'host' database: 'all' user: 'pglogical' address: '10.122.207.181/32' auth_method: 'trust' order: '010' 'LOG_REP_2': type: 'host' database: 'replication' user: 'pglogical' address: '10.122.207.181/32' auth_method: 'trust' order: '011'Zmiana parametrów po stronie publishera (po zmianie restart)
postgresql_server_config_entry: 'max_replication_slots': {value: '3'} --minimalna wartość ' 'wal_level': {value: 'logical'}Zmiana parametrów po stronie subscribera (po zmianie restart):
postgresql_server_config_entry: 'max_replication_slots': {value: '3'} --minimalna wartość ' 'wal_level': {value: 'logical'}
Zestawienie replikacji
Podejmujemy decyzję co do zakresu replikacji
Błędy
Krytyczne jest wszystko, co objawia się dezaktywacją slotu:

Nieaktywny slot modyfikuje działanie procesu checkpointera, obchodząc konfigurację - dopóki slot nie stanie się aktywny na powrót lub nie zostanie usunięty odkładają się dzienniki transakcji (co bardzo szybko prowadzi do przepełnienia przestrzeni dyskowej i zatrzymania bazy).
Najczęstszą przyczyną
Postgres jest dosyć wylewnym i elokwentnym narząedziem, więc większość problemów jest jasna.
2021-05-11T11:58:49.092983+02:00 paybm2-pgl-test.postgresql.dc0 postgres[112590]: [905494-1] 2021-05-11 11:58:49.092 CEST @ 112590 ERROR: logical replication target relation "public.t1" is missing some replicated columns
Sequence data is not replicated. The data in serial or identity columns backed by sequences will of course be replicated as part of the table, but the sequence itself would still show the start value on the subscriber. If the subscriber is used as a read-only database, then this should typically not be a problem. If, however, some kind of switchover or failover to the subscriber database is intended, then the sequences would need to be updated to the latest values, either by copying the current data from the publisher (perhaps using pg_dump) or by determining a sufficiently high value from the tables themselves.
Replikacja logiczna nie kopiuje tabel oraz roli, trzeba więc zrobić to ręcznie. Logujemy się na użytkownika postgres na masterze
Po czym przesyłamy pliki na slave
Aby postgres mógł skorzystać z tych plików należy przenieść je do lokalizacji /var/lib/pgsql/ oraz nadać odpowiednie uprawnienia
Logujemy się na użytkownika postgres na slave, po czym wykonujemy polecenie
W tym momencie jesteśmy gotowi, aby zacząć zestawiać replikację. Na masterze wykonujemy serię poleceń ( jeśli interesuje nas replikacja wszystkich tabel ):
Jeśli interesuje nas replikacja pojedynczych tabel tabel ostatnie polecenie powinno wyglądać:
UWAGA!
Jeśli na Masterze zostanie dodana nowa kolumna do którejś z tabel replikacja zatrzyma się, a slave będzie oczekiwał aż dodamy mu odpowiednią kolumnę. Po dodaniu kolumny na slave'ie replikacja zacznie zestawiać się ponownie.Sequence data is not replicated. The data in serial or identity columns backed by sequences will of course be replicated as part of the table, but the sequence itself would still show the start value on the subscriber. If the subscriber is used as a read-only database, then this should typically not be a problem. If, however, some kind of switchover or failover to the subscriber database is intended, then the sequences would need to be updated to the latest values, either by copying the current data from the publisher (perhaps using pg_dump) or by determining a sufficiently high value from the tables themselves.