Chcesz zestawić replikę PostgreSQL, ale gubisz się w pojęciach: fizyczna, logiczna, strumieniowa, synchroniczna, oparta na archiwum WAL.
To nie są konkurencyjne produkty, tylko różne wymiary tej samej mechaniki: co replikujemy (całość plików vs wybrane tabele), jak dostarczamy zmiany (strumień vs archiwum) i czy czekamy na potwierdzenie (async vs sync).
Dobierz rodzaj do celu: pełna kopia i failover to replikacja fizyczna strumieniowa, selektywne przesyłanie danych i migracje między wersjami to replikacja logiczna, a zero utraty danych to tryb synchroniczny.
PostgreSQL oferuje kilka mechanizmów replikacji i łatwo się w nich pogubić, bo nazwy się przenikają. Uporządkujmy to raz a dobrze: pokażemy, czym różni się replikacja fizyczna od logicznej, strumieniowa od archiwalnej i synchroniczna od asynchronicznej, oraz którą wybrać do konkretnego zadania.
Jak to wygląda w praktyce
Typowo administrator wie, że "potrzebuje repliki", ale nie wie, jaki dokładnie mechanizm ustawić. Czyta dokumentację i widzi terminy, które wydają się zamienne: raz mowa o wysyłaniu WAL strumieniem, raz o kopiowaniu segmentów z archiwum, raz o publikacjach i subskrypcjach. Efektem bywa źle dobrane rozwiązanie: ktoś stawia replikę logiczną, żeby mieć failover całej bazy, i dziwi się, że nie replikuje ona zmian schematu ani sekwencji tak, jak oczekiwał. Albo odwrotnie, ktoś próbuje replikować fizycznie pojedynczą tabelę do innej bazy, co jest niemożliwe, bo replikacja fizyczna działa na poziomie całego klastra. Wybór zaczyna się od jasnego celu.
Dlaczego tak się dzieje
Zamieszanie bierze się stąd, że replikacja w PostgreSQL to kilka niezależnych osi decyzji, a nie jedna lista opcji. Pierwsza oś to poziom: replikacja fizyczna kopiuje bajt w bajt zmiany z WAL i odtwarza cały klaster jako bliźniaczą kopię (te same pliki, ta sama wersja, identyczna struktura). Replikacja logiczna dekoduje WAL do zmian logicznych (wstaw, zmień, usuń wiersz) i przesyła tylko wybrane tabele, pozwalając na różne wersje po obu stronach i zapis na odbiorcy. Druga oś to sposób dostarczania: strumieniowo, gdzie replika ciągnie WAL na bieżąco po połączeniu sieciowym, albo z archiwum, gdzie odtwarza gotowe pliki WAL zrzucone przez archive_command. Trzecia oś to potwierdzanie: asynchronicznie (primary nie czeka na replikę, minimalny narzut, ryzyko utraty ostatnich transakcji przy awarii) albo synchronicznie (primary czeka na potwierdzenie standby, zero utraty danych kosztem opóźnienia zapisów).
Jak to rozwiązać krok po kroku
Nazwij cel: gorąca kopia całej bazy do failoveru, skalowanie odczytów, selektywne przesyłanie kilku tabel do innej bazy czy migracja między wersjami głównymi. Cel przesądza o poziomie replikacji.
Do failoveru i skalowania odczytów całego klastra wybierz replikację fizyczną strumieniową (hot-standby). Standby jest wierną kopią primary i można na nim czytać.
Do przesyłania wybranych tabel, integracji między systemami i migracji między wersjami głównymi wybierz replikację logiczną opartą na publikacjach i subskrypcjach. Odbiorca może mieć nowszą wersję i własne dodatkowe obiekty.
Zdecyduj o dostarczaniu: strumieniowo dla małego opóźnienia i bieżącej synchronizacji, a archiwum WAL jako uzupełnienie, żeby domknąć luki, gdy replika chwilowo odpadnie.
Zdecyduj o trybie potwierdzania: asynchroniczny domyślnie (wydajność), synchroniczny, gdy nie możesz stracić żadnej zatwierdzonej transakcji. Pamiętaj, że synchroniczny bez działającej repliki potrafi wstrzymać zapisy na primary.
Dobierz komplet parametrów pod wybór: dla fizycznej między innymi wal_level na poziomie replica, sloty replikacyjne i hot_standby; dla logicznej wal_level ustawiony na logical oraz publikacje i subskrypcje.
Jak sprawdzić, że zadziałało
Sprawdź, czy realny mechanizm zgadza się z zamiarem. Dla replikacji fizycznej na primary zajrzyj do pg_stat_replication i potwierdź stan streaming oraz, jeśli chcesz trybu synchronicznego, kolumnę sync_state równą sync. Dla replikacji logicznej na wydawcy sprawdź pg_publication i aktywne sloty w pg_replication_slots, a na subskrybencie stan w pg_stat_subscription. Na końcu wykonaj test danych zgodny z wyborem: dla fizycznej odczytaj świeży zapis na standby, dla logicznej sprawdź, czy zmiana w replikowanej tabeli dotarła do subskrybenta, a w tabeli nieobjętej publikacją - nie. Zgodność zachowania z celem to dowód dobrego wyboru.
PostgreSQL nie ma jednej listy opcji, tylko kilka niezależnych wymiarów. Pierwszy to poziom: replikacja fizyczna (kopia całego klastra bajt w bajt) albo logiczna (wybrane tabele na poziomie wierszy). Drugi to sposób dostarczania: strumieniowy (replika ciągnie WAL na bieżąco) albo z archiwum WAL (odtwarzanie gotowych segmentów). Trzeci to potwierdzanie: asynchroniczny (bez czekania na replikę) albo synchroniczny (primary czeka na potwierdzenie standby). Realna konfiguracja to wybór po jednej wartości z każdej osi.
Którą replikację wybrać do failoveru całej bazy?
Replikację fizyczną strumieniową w trybie hot-standby. Standby jest wierną kopią primary, obejmuje cały klaster i można na nim czytać, a w razie awarii primary da się go szybko promować do nowej roli głównej. Do tego dobierasz tryb potwierdzania: asynchroniczny dla wydajności albo synchroniczny, jeśli nie możesz stracić żadnej zatwierdzonej transakcji. Replikacja logiczna do pełnego failoveru się nie nadaje, bo nie przenosi automatycznie zmian schematu ani sekwencji.
Czym różni się replikacja synchroniczna od asynchronicznej?
W trybie asynchronicznym primary zatwierdza transakcję i nie czeka, aż replika ją odbierze, więc narzut jest minimalny, ale przy nagłej awarii primary można stracić ostatnie transakcje, które nie dotarły jeszcze do standby. W trybie synchronicznym primary czeka na potwierdzenie od repliki przed zakończeniem zapisu, co daje zero utraty zatwierdzonych danych kosztem większego opóźnienia. Uwaga: synchroniczny bez działającej repliki potrafi wstrzymać zapisy na primary, dopóki standby nie wróci.
Po czym poznać, że replikacja działa w trybie synchronicznym?
Na primary zajrzyj do widoku pg_stat_replication i sprawdź kolumnę sync_state. Wartość sync oznacza, że dana replika jest replikami synchroniczną i primary czeka na jej potwierdzenie, a wartość async oznacza tryb asynchroniczny. Tryb synchroniczny konfiguruje się przez parametr synchronous_standby_names, gdzie wskazujesz nazwy replik, na które primary ma czekać. Warto pamiętać, że tryb synchroniczny wymaga co najmniej jednej sprawnej repliki synchronicznej, inaczej zapisy się wstrzymają.
Komentarze (0)
Brak komentarzy...