PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

PostgreSQL 13:Nie pozwól, aby sloty zabiły twój podstawowy

Jedną z interesujących funkcji PostgreSQL od wersji 9.4 jest możliwość kontrolowania usuwania plików WAL za pomocą gniazd replikacji. Ciemną stroną jest to, że gniazda replikacji mogą powodować zapełnianie dysków starym WAL-em, zabijając główny serwer produkcyjny. W tym artykule wyjaśniam gniazda replikacji PostgreSQL i jak nowa funkcja PostgreSQL 13 pomaga zapobiegać temu problemowi.

Produkcja WAL

Jak wiecie, WAL jest tworzony dla zmian w bazie danych na serwerze głównym:wstawek, aktualizacji, i tak dalej . Bardziej aktywna baza danych wygeneruje więcej WAL — na bardzo aktywnym serwerze może być produkowanych wiele gigabajtów WAL na minutę. WAL jest zapisywany do plików o nazwach w rosnącej kolejności numerycznej, a pliki mają zawsze ten sam rozmiar (domyślnie i typowo 16 MB). Gdy dane w pliku nie są już potrzebne, można go odzyskać , co oznacza zmianę jego nazwy na pozycję o wyższym numerze w sekwencji, aby później można było ją uzupełnić nowymi danymi.

(Istnieją specjalne sytuacje, takie jak wzrost aktywności, który prowadzi do tworzenia dodatkowych plików; gdy później wzrost ten słabnie, te dodatkowe pliki są usuwane, a nie poddawane recyklingowi.)

Ponieważ wszystkie operacje związane z zapisem bazy danych generują WAL, dostępność miejsca na dysku ma kluczowe znaczenie. Gdy dysk przechowujący WAL jest pełny, serwer nie będzie w stanie przetwarzać nowych transakcji i może utknąć lub, co gorsza:może się całkowicie przewrócić. Jest to więc sytuacja, której należy unikać za wszelką cenę.

Gniazda replikacji

Replikacja w PostgreSQL działa na zasadzie przetwarzania plików WAL. Aby to zadziałało, wszystkie pliki WAL muszą być przejściowo dostępne, dopóki nie zostaną przetworzone. Dlatego potrzebny jest mechanizm informujący główne kierownictwo WAL, aby nie odtwarzało ani nie usuwało plików.

Wprowadź gniazda replikacji. Automaty to mechanizm, który wskazuje, że to wykonywana przez nas kopia zapasowa będzie wymagać tego plik WAL i czy możesz go jeszcze nie usuwać; lub to replika nadal nie przetworzyła tego Plik WAL, więc czy można go zostawić w spokoju na chwilę.

Same gniazda replikacji zajmują bardzo mało miejsca na dysku. Przechowują tylko niewielką ilość metadanych, w tym wskaźnik do pozycji w WAL. Ale dane WAL, które chroni, to inna sprawa:w wysoce aktywnym serwerze można je mierzyć w gigabajtach lub gorzej.

Zużycie WAL

Dostarczenie danych do fizycznej repliki oznacza skopiowanie danych WAL z jej głównego serwera. Podobnie replika logiczna musi odczytywać dane WAL (i przesyłać zinterpretowaną wersję do repliki). Odczytywana pozycja WAL jest tym, co slot śledzi. Gdy replika w jakiś sposób zabezpieczy dane WAL, gniazdo można przesunąć; informuje to zarządzanie WAL w systemie podstawowym, że plik WAL jest wtedy dostępny do usunięcia. Dzieje się to w sposób ciągły, gdy replika jest aktywna, tak że WAL na serwerze podstawowym będzie wykorzystywał tę samą ilość miejsca na dysku, a może tylko trochę więcej. Nawet dwa razy więcej lub dziesięć razy więcej może być do przyjęcia, w zależności od warunków.

Problem polega na tym, że jeśli replika całkowicie umrze i nie będzie się regenerować przez długi czas; lub replika jest zniszczona i administrator zapomni usunąć gniazdo replikacji; albo slot jest zapomnianą pozostałością po jakimś eksperymencie; lub nawet replika jest zasilana przez wolne łącze sieciowe, wtedy zarezerwowany WAL będzie rósł bez ograniczeń. A to staje się tykającą bombą.

Ograniczenie rozmiaru boksu

Aby rozwiązać ten problem, Kyotaro Horiguchi pracował od lutego 2017 r. nad łatką PostgreSQL, aby ograniczyć rozmiar WAL zarezerwowany przez slot. Po bardzo długim procesie przeglądu i przeróbek zintegrowałem go z PostgreSQL 13, poprawiając zarządzanie farmami PostgreSQL o wysokiej dostępności.

Główną zasadą jest to, że lepiej zabić replikę (poprzez unieważnienie jej slotu; więcej o tym poniżej) niż zabijać serwer główny, który zasila tę replikę i wyłączać z nią całą produkcję.

Sposób, w jaki to działa, jest dość prosty:ustaw max_slot_wal_keep_size (dokumentacja) w postgresql.conf do maksymalnej ilości miejsca na dysku WAL, którą mogą zarezerwować gniazda replikacji. Jeśli slot osiągnie ten punkt i wystąpi punkt kontrolny, zostanie on oznaczony jako nieważny i niektóre pliki WAL mogą zostać usunięte. Jeśli slot był aktywnie używany przez walsendera proces, ten proces zostanie zasygnalizowany, aby się zakończył. Jeśli walsender uruchomi się ponownie, okaże się, że niezbędne pliki WAL już tam nie będą. Replika korzystająca z tego gniazda będzie musiała zostać ponownie sklonowana.

Jeśli max_slot_wal_keep_size wynosi zero, co jest wartością domyślną, wtedy nie ma limitu. Nie polecam tego, ponieważ prowadzi to do awarii, gdy gniazda wypełniają dysk.

Monitorowanie stanu gniazda

Dołączone są również niektóre funkcje monitorowania. Istotne są dwie kolumny w pg_replication_slots. Najważniejszym z nich jest wal_status . Jeśli ta kolumna jest reserved , to slot wskazuje na dane w max_wal_size; jeśli jest extended potem przekroczył max_wal_size , ale nadal jest chroniony przez wal_keep_size lub max_slot_wal_keep_size (również gdy max_slot_wal_keep_size wynosi zero). Każdy stan jest dobry i normalny. Jednak gdy slot przekroczy limit, najpierw staje się unreserved , co oznacza, że ​​jest w bezpośrednim niebezpieczeństwie, ale może się zregenerować, jeśli jest wystarczająco szybkie. Ostatecznie status staje się lost gdy pliki WAL zostały usunięte i odzyskanie nie jest możliwe.

Druga kolumna to safe_wal_size :pokazuje liczbę bajtów WAL, które można zapisać, zanim ten slot znajdzie się w niebezpieczeństwie usunięcia plików WAL. Sugerujemy, aby uważnie obserwować tę kolumnę w systemie monitorowania i uruchamiać alerty, gdy stanie się niski. Zero lub minus oznacza, że ​​replika będzie martwa, gdy tylko pojawi się punkt kontrolny:

SELECT slot_name, active, wal_status, safe_wal_size
  FROM pg_catalog.pg_replication_slots;

Wierzymy, że ta nowa funkcja sprawia, że ​​konserwacja replik jest łatwiejsza i bardziej niezawodna; miejmy nadzieję, że z powodu tych problemów nie zobaczymy już więcej katastrof związanych z przerwą w produkcji.

(Uwaga:safe_wal_size został wprowadzony w 13beta3, więc zapoznaj się z aktualną dokumentacją, w przeciwnym razie zobaczysz min_safe_lsn zamiast. Zignoruj ​​to.)

Dzięki

Specjalne podziękowania dla Kyotaro Horiguchi za pracę nad rozwiązaniem tego problemu. Kilku recenzentów zagłębiło się w to, wśród których chciałbym szczególnie podziękować Masahiko Sawada, Fujii Masao, Jehan-Guillaume de Rorthais i Amit Kapila (w dowolnej kolejności).


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Podpowiedź w PostgreSQL

  2. Przyznaj wszystko w określonym schemacie w bazie danych do roli grupowej w PostgreSQL

  3. Zapytanie Postgresql między zakresami dat

  4. PostgreSQL GROUP_CONCAT() Odpowiednik

  5. Przekazywanie param do DB .execute dla listy WHERE IN... INT