Co dzieje się w punkcie kontrolnym PostgreSQL?

22

Oto część mojego dziennika kontrolnego:

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

Zauważyłem, że czasami nasza baza danych jest bardzo wolna - widać bardzo dużą liczbę normalnie krótkich zapytań, które utknęły na dłużej niż obecnie. Dzieje się to regularnie, bez wyraźnego winowajcy.

Pytanie: Czy może to powodować punkt kontrolny? Co dzieje się w fazie „synchronizacji” punktu kontrolnego?

Konrad Garus
źródło

Odpowiedzi:

32

Podczas działania PostgreSQL rejestruje zmiany w plikach dziennika transakcji, ale nie od razu opróżnia je do rzeczywistych tabel bazy danych. Zwykle po prostu zachowuje zmiany w pamięci i zwraca je z pamięci, gdy są wymagane, chyba że RAM zacznie się zapełniać i musi je zapisać.

Oznacza to, że jeśli ulegnie awarii, tabele na dysku nie będą aktualne. Musi ponownie odtworzyć dzienniki transakcji, stosując zmiany w tabelach na dysku, zanim będzie mógł rozpocząć tworzenie kopii zapasowej. To może zająć trochę czasu dla dużej, zajętej bazy danych.

Z tego powodu i aby dzienniki transakcji nie rosły wiecznie, PostgreSQL okresowo robi punkt kontrolny, w którym upewnia się, że DB jest w stanie czystym. Opróżnia wszystkie oczekujące zmiany na dysku i przetwarza dzienniki transakcji, które były używane do przechowywania rejestru zmian po awarii.

Ten kolor odbywa się w dwóch fazach:

  • Buforowane write()brudne shared_buffersdo stołów; i
  • fsync() plików, których dotyczy problem, aby upewnić się, że zmiany naprawdę trafiły na dysk

Oba mogą zwiększyć obciążenie dysku we / wy. Rywalizacja spowodowana tymi zapisami może spowolnić odczyty, a także spowolnić opróżnianie segmentów WAL, które są wymagane do zatwierdzenia transakcji.

To od dawna wyzwanie, ale pogarsza się, ponieważ widzimy systemy z coraz większą pamięcią RAM, aby mogły buforować więcej danych i dłużej je zapisywać. Obecnie trwa dyskusja między społecznościami Linuksa i PostgreSQL, jak poradzić sobie z tym problemem, jak omówiono w tym artykule LWN.net . (LWN.net nie będzie w stanie pisać tego wspaniałego dzieła, jeśli ludzie się nie subskrybują. Jestem subskrybentem i udostępniam ten link, ponieważ jest on użyteczny i pouczający. Proszę rozważyć subskrypcję, jeśli chcesz zobaczyć więcej tego coś w tym rodzaju).

Najważniejszą rzeczą, jaką możesz zrobić, aby zmniejszyć wpływ punktów kontrolnych w tym momencie, jest rozłożenie aktywności punktów kontrolnych poprzez zwiększenie, checkpoint_completion_targettak aby więcej danych zostało zapisanych do czasu przybycia końcowego punktu kontrolnego. Jest to jednak kosztowne - jeśli zaktualizujesz stronę (powiedzmy) dziesięć razy, może zostać zapisana na dysk wiele razy przed punktem kontrolnym z wysokim celem ukończenia, nawet jeśli dla bezpieczeństwa po awarii musiała być napisana tylko raz. Wyższy cel ukończenia zapewnia płynniejsze wzorce we / wy, ale większy ogólny koszt we / wy.

Inną rzeczą, którą możesz zrobić, to pomóc systemowi operacyjnemu, aby natychmiast zaczął zapisywać dane po zapisaniu buforowanym. To jest jak ustawienie jądra checkpoint_completion_targeti ma podobny kompromis. Zobacz dokumentację vm Linux , w szczególności dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.

Craig Ringer
źródło
Zapis jest rozłożony na długi czas i nie sądzę, że powoduje problemy. A co z synchronizacją, czy przypadkiem jest to operacja typu stop-the-world?
Konrad Garus
@KonradGarus Synchronizacja nie powinna być operacją typu stop-the-world, ale często tak jest. Przeczytaj artykuł, do którego odsyłam powyżej, jest to bardzo aktualne i przydatne podsumowanie problemów, aczkolwiek z dość technicznego punktu widzenia. Krótka wersja to „fsync () w Linuksie ma tendencję do całkowitego niszczenia wydajności dowolnego wejścia / wyjścia współbieżnego z fsync ()”. Możesz to złagodzić za pomocą opcji strojenia wymienionych powyżej, aby zmniejszyć ilość, która musi zostać wypłukana przez fsync.
Craig Ringer
1

Płukanie brudne bufory systemu plików OS spowodowany przez przekroczenie dirty_byteslub dirty_ratio jest pierwszego planu operacji blokowania!

Do dostrajania jądra dirty_bytes, dirty_background_bytes, dirty_ratio, dirty_background_ratioi dirty_centisecskontrola spłukiwania brudne bufory systemu plików OS na dysku. dirty_bytesjest progiem w bajtach, dirty_ratiojest progiem jako stosunek całkowitej pamięci. dirty_background_bytesi dirty_background_ratiosą podobnymi progami, ale płukanie odbywa się w tle i nie blokuje innych operacji odczytu / zapisu, dopóki się nie zakończy. dirty_centisecsto ile centisekund może minąć przed zainicjowaniem koloru.

Ostatnio wartości domyślne dla tych tunerów zostały obniżone w Linuksie, ponieważ rozmiar pamięci dla nowoczesnych maszyn znacznie się zwiększył. Nawet współczynniki 5 i 10% dla dirty_background_ratioi dirty_rationa maszynie 256 GB mogą zalać system I / O.

Strojenie dirty_background_byteslub dirty_background_ratiorozpoczęcie opróżniania brudnych buforów w tle jest trudne. Na szczęście możesz dostroić te ustawienia bez konieczności zatrzymywania PostgreSQL lub hosta poprzez echo nowych wartości w odpowiednich plikach:

$ sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

na przykład, aby ustawić liczbę zabrudzonych bajtów, aby uruchomić czyszczenie tła. Jeśli używasz podtrzymaniem bateryjnym, kondensator oparciem lub pamięci flash karty RAID (ty nie chcesz zachować swoje dane w przypadku awarii, prawda?) Rozpocząć od strojenia dirty_background_bytesdo 1/2 rozmiar bufora cache zapisu i dirty_bytesdo 3/4 tego rozmiaru. Monitoruj swój profil we / wy za pomocą iostats, a jeśli nadal występują problemy z opóźnieniem, co oznacza, że ​​obciążenie zapisu w bazie danych wciąż przytłacza opróżnianie pamięci podręcznej bufora plików. Zmniejsz wartości, dopóki opóźnienie nie ulegnie poprawie lub rozważ uaktualnienie podsystemu we / wy. Karty FusionIO i dyski SSD to dwie możliwości ekstremalnej przepustowości we / wy.

Powodzenia!

Bobl
źródło
Twój komentarz na temat „brudnych” danych jest istotny dla powolności. Zasadniczo: im większy stosunek zabrudzenia, tym więcej bufora jest przydzielane dla brudnych danych przed uruchomieniem opróżniania. Zatem minimalizacja opóźnień opróżniania oznacza zwiększenie bufora zabrudzonego lub zwiększenie czasu, przez jaki brudne dane mogą pozostać w pamięci.
Peter Teoh