Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
Zbyt wolny start - pg_prewarm i rozgrzewanie cache
Zimny start to codzienny problem po planowym restarcie, aktualizacji albo failoverze. Baza po ponownym uruchomieniu ma pusty bufor, więc pierwsza fala zapytań uderza prosto w dysk i użytkownicy odczuwają to jako sekundowe zamulenie. Rozszerzenie pg_prewarm pozwala rozgrzać cache z góry, zanim ruch produkcyjny do nas dotrze. To jeden z najprostszych i najtańszych chwytów wydajnościowych w PostgreSQL.
Tuż po systemctl restart postgresql to samo zapytanie, które normalnie zwraca wynik w kilkanaście milisekund, potrafi trwać sekundy. W EXPLAIN (ANALYZE, BUFFERS) widać wtedy wysokie shared read, czyli strony pobierane z dysku, zamiast shared hit, czyli trafień w pamięć. Po kilku minutach normalnego ruchu wszystko wraca do normy, bo bufor sam się zapełnia najczęściej używanymi danymi. Problem jest szczególnie dotkliwy przy dużych tabelach raportowych oraz na replikach, które po promocji na primary mają zupełnie zimny cache. Użytkownik widzi to jako niespodziewane spowolnienie serwisu zaraz po oknie serwisowym.
PostgreSQL trzyma często używane strony danych w obszarze shared_buffers, a system operacyjny dodatkowo buforuje pliki na swoim poziomie. Oba te cache są ulotne - restart procesu bazy czyści shared_buffers, a restart całej maszyny czyści także cache systemu. Po starcie baza nie wie z góry, które dane będą potrzebne, więc uczy się tego dopiero z napływających zapytań. Każde pierwsze odwołanie do strony, której nie ma w pamięci, oznacza fizyczny odczyt z dysku, a odczyt losowy jest wolniejszy niż odczyt z RAM o rzędy wielkości. Dlatego przez pierwsze minuty po restarcie baza jest związana wejściem-wyjściem, a nie procesorem.
CREATE EXTENSION IF NOT EXISTS pg_prewarm;. Rozszerzenie jest częścią pakietu contrib, więc nie wymaga niczego spoza standardowej dystrybucji.SELECT pg_prewarm('zamowienia');. Funkcja wczyta wszystkie strony tej relacji do bufora. Tak samo możesz rozgrzać indeks, podając jego nazwę.SELECT pg_prewarm('zamowienia', 'buffer');.ALTER SYSTEM SET shared_preload_libraries = 'pg_prewarm';, a następnie zrestartuj serwer.Najprostszy dowód to EXPLAIN (ANALYZE, BUFFERS) na zapytaniu do rozgrzanej tabeli tuż po starcie. Jeśli w wynikach dominuje shared hit, a shared read jest bliskie zera, dane są już w pamięci. Sama funkcja pg_prewarm zwraca liczbę wczytanych bloków, więc od razu widzisz, ile stron trafiło do bufora. Przy autoprewarm sprawdź, czy w logu po starcie pojawił się komunikat o wczytaniu zapisanych bloków. Ostatecznym testem jest porównanie czasu pierwszego zapytania po restarcie z rozgrzewaniem i bez niego - różnica bywa dziesięciokrotna.
Wróć do listy: 100 najczęstszych pytań i problemów z 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

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
Komentarze (0)
Brak komentarzy...