Punkty kontrolne mogą być główną przeszkodą w intensywnych instalacjach PostgreSQL. Pierwszym krokiem w kierunku identyfikacji problemów w tym obszarze jest monitorowanie częstotliwości ich występowania, dzięki czemu ostatnio do bazy danych dodano łatwiejszy w użyciu interfejs.
Punkty kontrolne to okresowe operacje konserwacyjne, które wykonuje baza danych, aby upewnić się, że wszystko, co przechowuje w pamięci, zostało zsynchronizowane z dyskiem. Pomysł polega na tym, że po ukończeniu jednego można wyeliminować potrzebę martwienia się o starsze wpisy umieszczane w dzienniku zapisu z wyprzedzeniem bazy danych. Oznacza to mniej czasu na odzyskanie danych po awarii.
Problem z punktami kontrolnymi polega na tym, że mogą one być bardzo intensywne, ponieważ ich ukończenie wymaga zapisania na dysk każdego bitu zmienionych danych w buforze bufora bazy danych. Do PostgreSQL 8.3 dodano wiele funkcji, które pozwalają lepiej monitorować obciążenie punktu kontrolnego i obniżać go poprzez rozłożenie aktywności na dłuższy okres czasu. Napisałem długi artykuł o tych zmianach, zatytułowany Punkty kontrolne i Zapis w tle, który omawia, co się zmieniło, ale jest to dość sucha lektura.
Prawdopodobnie chcesz wiedzieć, jak monitorować punkty kontrolne w systemie produkcyjnym i jak je rozpoznać jeśli zdarzają się zbyt często. Mimo że sytuacja uległa poprawie, „skoki w punktach kontrolnych”, w których operacje we/wy na dysku stają się naprawdę duże, są nadal możliwe, nawet w obecnych wersjach PostgreSQL. I nie pomaga to, że domyślna konfiguracja jest dostosowana do bardzo małej ilości miejsca na dysku i szybkiego odzyskiwania po awarii, a nie wydajności. Parametr checkpoint_segments, który jest jednym z danych wejściowych określających, jak często pojawia się punkt kontrolny, ma domyślną wartość 3, co wymusza punkt kontrolny po zaledwie 48 MB zapisów.
Częstotliwość punktów kontrolnych można sprawdzić na dwa sposoby. Możesz włączyć log_checkpoints i obserwować, co dzieje się w logach. Możesz także użyć widoku pg_stat_bgwriter, który podaje liczbę każdego z dwóch źródeł punktów kontrolnych (upływający czas i występujące zapisy), a także statystyki dotyczące tego, ile pracy wykonali.
Główny problem z ułatwieniem tego do niedawna nie można było zresetować liczników wewnątrz pg_stat_bgwriter. Oznacza to, że musisz zrobić migawkę ze znacznikiem czasu, odczekać chwilę, zrobić kolejną migawkę, a następnie odjąć wszystkie wartości, aby uzyskać przydatne statystyki z danych. To jest ból.
Dość bólu, że napisałem łatkę, aby to ułatwić. W obecnej wersji rozwojowej bazy danych możesz teraz wywołać funkcję pg_stat_reset_shared(‘bgwriter’) i ponownie ustawić wszystkie te wartości z powrotem na 0. Pozwala to na zastosowanie praktyki, która była powszechna w PostgreSQL. Przed wersją 8.3 istniał parametr o nazwie stats_reset_on_server_start, który można było włączyć. Spowoduje to zresetowanie wszystkich wewnętrznych statystyk serwera za każdym razem, gdy go uruchomisz. Oznaczało to, że możesz wywołać przydatną funkcję pg_postmaster_start_time(), porównać z bieżącym czasem i zawsze mieć dokładną liczbę operacji/sekundę dowolnej statystyki dostępnej w systemie.
Nadal nie jest to automatyczne, ale teraz że zresetowanie tych wspólnych elementów jest możliwe, możesz to zrobić sam. Pierwszym kluczem jest zintegrowanie czyszczenia statystyk z sekwencją startową serwera. Taki skrypt zadziała:
pg_ctl start -l $PGLOG -w
psql -c "select pg_stat_reset();"
psql -c "select pg_stat_reset_shared('bgwriter');"
Zwróć uwagę na „-w” w poleceniu start – to sprawi, że pg_ctl będzie czekać, aż serwer zakończy uruchamianie, zanim powróci, co jest niezbędne, jeśli chcesz natychmiast wykonać przeciwko niemu instrukcję.
Jeśli już to zrobiłeś to, a czas uruchomienia serwera jest zasadniczo taki sam, jak w momencie, gdy statystyki zapisu w tle rozpoczęły zbieranie, możesz teraz użyć tego zabawnego zapytania:
SELECT
total_checkpoints,
seconds_since_start / total_checkpoints / 60 AS minutes_between_checkpoints
FROM
(SELECT
EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time())) AS seconds_since_start,
(checkpoints_timed+checkpoints_req) AS total_checkpoints
FROM pg_stat_bgwriter
) AS sub;
Uzyskaj prosty raport o tym, jak często w Twoim systemie występują punkty kontrolne. Wynik wygląda tak:
total_checkpoints | 9
minutes_between_checkpoints | 3.82999310740741
To, co robisz z tymi informacjami, to wpatrywanie się w średni przedział czasu i sprawdzanie, czy nie wydaje się to zbyt szybkie. Normalnie chciałbyś, aby punkt kontrolny pojawiał się nie częściej niż co pięć minut, a w zajętym systemie może być konieczne przesunięcie go do dziesięciu minut lub więcej, aby mieć nadzieję na dotrzymanie kroku. W tym przykładzie co 3,8 minuty jest prawdopodobnie zbyt szybkie — jest to system, który wymaga wyższego poziomu segmentów checkpoint_segments.
Użycie tej techniki do pomiaru interwału punktu kontrolnego pozwala wiedzieć, czy należy zwiększyć parametry segmenty_punktu_kontroli i limit czasu_punktu w kolejności aby osiągnąć ten cel. Możesz teraz obliczyć liczby ręcznie, a po dostarczeniu wersji 9.0 jest to coś, co możesz rozważyć całkowicie automatycznie – o ile nie masz nic przeciwko, aby statystyki znikały za każdym razem, gdy serwer zostanie ponownie uruchomiony.
Istnieje kilka innych interesujących sposobów aby przeanalizować dane, które zapewnia autor w tle w pg_stat_bgwriter, ale nie zamierzam dziś zdradzać wszystkich moich sztuczek.