Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Replika przestała się synchronizować - jak wznowić replikację

W skrócie

  • Replika hot-standby przestała nadążać za primary albo całkiem się rozłączyła i przestała odbierać zmiany.
  • Najczęściej brakuje na primary plików WAL, których replika jeszcze nie zdążyła pobrać (zostały usunięte), albo replika ma za mały limit opóźnienia i zabija własne odtwarzanie przy konfliktach.
  • Zdiagnozuj przyczynę po logach i widokach systemowych, przywróć dostarczanie WAL (slot replikacji lub archiwum), a przy zbyt dużym rozjeździe odtwórz replikę od nowa przez pg_basebackup.

Replikacja fizyczna strumieniowa w trybie hot-standby to podstawowy sposób utrzymania gorącej kopii bazy. Bywa jednak, że replika zatrzymuje się albo dryfuje coraz dalej od primary. Pokażemy, jak ustalić, dlaczego przestała się synchronizować, i jak wznowić replikację bez utraty danych.

Jak to wygląda w praktyce

Na replice rośnie opóźnienie: dane, które widzisz, są coraz starsze względem primary. W skrajnym przypadku proces WAL receiver na replice znika i połączenie replikacyjne nie odbudowuje się. W logu repliki pojawia się komunikat, że żądany segment WAL nie jest już dostępny na serwerze nadrzędnym, albo że odtwarzanie zostało przerwane z powodu konfliktu z zapytaniami. Na primary widok pg_stat_replication może w ogóle nie pokazywać tej repliki, co oznacza, że strumień jest zerwany. Aplikacja czytająca z repliki nagle serwuje nieaktualne dane, a próba przełączenia awaryjnego okazuje się ryzykowna, bo standby jest daleko w tyle.

Dlaczego tak się dzieje

Replikacja strumieniowa polega na tym, że replika pobiera z primary kolejne pliki WAL i je odtwarza. Jeśli replika na chwilę odpadnie (sieć, restart, przeciążenie) i wróci później, niż primary trzyma stare WAL-e, to potrzebnych segmentów już nie ma i strumienia nie da się wznowić. Bez slotu replikacyjnego primary nie wie, że ma je zachować, więc czyści je zgodnie z wal_keep_size i checkpointami. Drugi typowy powód to konflikty odtwarzania: długie zapytania na replice blokują nakładanie zmian, a parametr max_standby_streaming_delay decyduje, czy PostgreSQL poczeka, czy przerwie zapytanie. Zdarza się też zwykłe przeciążenie repliki, która nie nadąża odtwarzać WAL tak szybko, jak primary go generuje, co daje rosnące opóźnienie mimo poprawnego połączenia.

Jak to rozwiązać krok po kroku

  1. Zajrzyj do logu repliki i odczytaj konkretny komunikat: brak segmentu WAL, konflikt odtwarzania czy zerwane połączenie. To determinuje dalsze kroki.
  2. Na primary sprawdź pg_stat_replication (czy replika jest widoczna i jaki ma stan) oraz pg_replication_slots, jeśli używasz slotów. Na replice sprawdź opóźnienie funkcjami czasu odtwarzania.
  3. Jeśli brakuje segmentów WAL, a masz slot replikacyjny, upewnij się, że replika łączy się właśnie przez ten slot (parametr primary_slot_name). Slot każe primary zachować WAL, dopóki replika ich nie potwierdzi.
  4. Jeśli nie było slotu i WAL-e przepadły, ale masz archiwum WAL, skonfiguruj na replice pobieranie z archiwum (restore_command), żeby domknęła lukę z kopii archiwalnej.
  5. Przy konfliktach odtwarzania rozważ zwiększenie max_standby_streaming_delay lub włączenie hot_standby_feedback, żeby primary nie usuwał wersji wierszy potrzebnych długim zapytaniom na replice.
  6. Jeśli rozjazd jest zbyt duży i luki nie da się domknąć, przebuduj replikę od zera: zatrzymaj ją, wykonaj świeży pg_basebackup z primary (najlepiej z utworzeniem slotu), ustaw standby.signal i parametry połączenia, po czym wystartuj.
  7. Po wznowieniu obserwuj, czy opóźnienie maleje. Jeśli replika stale nie nadąża, sprawdź obciążenie dysku i procesora oraz to, czy sprzęt standby nie jest słabszy od primary.

Jak sprawdzić, że zadziałało

Na primary w widoku pg_stat_replication replika powinna być widoczna ze stanem streaming, a różnice między pozycjami wysłania, zapisu i odtworzenia WAL powinny być małe i stabilne. Na replice policz opóźnienie funkcją pg_last_xact_replay_timestamp() i porównaj z czasem bieżącym - powinno spadać do sekund. Wykonaj też prosty test end-to-end: zapisz znacznik na primary, a po chwili odczytaj go z repliki. Jeśli znacznik dociera szybko i opóźnienie się nie kumuluje, replikacja działa poprawnie.

Wróć do listy: 100 najczęstszych pytań i problemów z PostgreSQL

Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL

Sprawdź szkolenie: Administracja, replikacja i tuning baz danych PostgreSQL

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Szkolenie Zaawansowana administracja PostgreSQL - HA, DR, monitoring, skalowanie

Sprawdź szkolenie: Zaawansowana administracja PostgreSQL (HA, DR, monitoring, skalowanie)

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Dlaczego replika zgłasza brak segmentu WAL na primary?
Bo primary usunął pliki WAL, zanim replika zdążyła je pobrać. Dzieje się tak, gdy replika chwilowo odpadnie i wróci później, niż primary trzyma stare segmenty, a nie ma slotu replikacyjnego, który kazałby je zachować. Rozwiązania są dwa: użyj slotu replikacyjnego (parametr primary_slot_name), żeby primary trzymał WAL do potwierdzenia przez replikę, albo skonfiguruj na replice pobieranie z archiwum WAL przez restore_command, żeby domknęła lukę z kopii archiwalnej.
Jak sprawdzić, czy replika w ogóle jest połączona z primary?
Na primary zajrzyj do widoku pg_stat_replication. Jeśli replika jest tam widoczna ze stanem streaming, połączenie działa, a różnice między pozycjami wysłania, zapisu i odtworzenia WAL pokazują, jak bardzo standby jest w tyle. Jeśli repliki w tym widoku nie ma wcale, strumień jest zerwany i trzeba szukać przyczyny w logu repliki (brak WAL, zerwana sieć, konflikt). Na replice opóźnienie zmierzysz funkcją pg_last_xact_replay_timestamp porównaną z czasem bieżącym.
Kiedy trzeba przebudować replikę od zera zamiast ją wznawiać?
Gdy rozjazd jest zbyt duży i brakujących segmentów WAL nie da się już dostarczyć ani ze slotu, ani z archiwum. W takim przypadku zatrzymaj replikę, wykonaj świeży pg_basebackup z primary (najlepiej z utworzeniem slotu), ustaw plik standby.signal oraz parametry połączenia i wystartuj. Przebudowa jest pewniejsza niż ręczne łatanie luk w WAL. Po starcie obserwuj, czy opóźnienie maleje, i sprawdź, czy sprzęt standby nie jest za słaby, by nadążać.
Co zrobić, gdy odtwarzanie na replice jest przerywane przez konflikt z zapytaniami?
To konflikt odtwarzania: długie zapytania na standby blokują nakładanie zmian z primary. Masz dwie dźwignie. Zwiększenie parametru max_standby_streaming_delay daje zapytaniom więcej czasu, zanim zostaną przerwane na rzecz nakładania WAL. Włączenie hot_standby_feedback sprawia, że standby informuje primary o trwających zapytaniach, więc primary nie usuwa wersji wierszy, których replika jeszcze potrzebuje. Trzeba wyważyć oba parametry, bo agresywne ustawienia mogą zwiększać opóźnienie albo puchnięcie na primary.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...