Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Zbyt wolny start - pg_prewarm i rozgrzewanie cache

W skrócie

  • Zaraz po restarcie PostgreSQL pierwsze zapytania są dramatycznie wolne, choć po chwili baza wraca do normalnej prędkości.
  • Restart czyści bufor bazy i cache systemu, więc każda strona danych musi najpierw wrócić z dysku - to tak zwany zimny start.
  • Używamy rozszerzenia pg_prewarm, aby po starcie wczytać najważniejsze tabele i indeksy do pamięci, a autoprewarm robi to automatycznie po każdym restarcie.

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.

Jak to wygląda w praktyce

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.

Dlaczego tak się dzieje

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.

Jak to rozwiązać krok po kroku

  1. Zainstaluj rozszerzenie w wybranej bazie: CREATE EXTENSION IF NOT EXISTS pg_prewarm;. Rozszerzenie jest częścią pakietu contrib, więc nie wymaga niczego spoza standardowej dystrybucji.
  2. Ręcznie rozgrzej konkretną tabelę: SELECT pg_prewarm('zamowienia');. Funkcja wczyta wszystkie strony tej relacji do bufora. Tak samo możesz rozgrzać indeks, podając jego nazwę.
  3. Aby wczytać dane wprost do shared_buffers, a nie tylko do cache systemu, podaj tryb: SELECT pg_prewarm('zamowienia', 'buffer');.
  4. Żeby rozgrzewanie działo się samo po każdym restarcie, włącz autoprewarm. Dodaj bibliotekę do konfiguracji: ALTER SYSTEM SET shared_preload_libraries = 'pg_prewarm';, a następnie zrestartuj serwer.
  5. Z włączonym autoprewarm proces w tle co jakiś czas zapisuje listę stron aktualnie w buforze do pliku, a po starcie automatycznie je wczytuje - nie musisz robić nic więcej.
  6. Dla scenariusza produkcyjnego przygotuj krótki skrypt SQL, który po planowym restarcie rozgrzewa kluczowe tabele i indeksy raportowe, i uruchamiaj go tuż przed wpuszczeniem ruchu.

Jak sprawdzić, że zadziałało

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

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

Do czego służy rozszerzenie pg_prewarm?
pg_prewarm służy do wczytania wybranych tabel i indeksów do pamięci zaraz po starcie serwera, zanim dotrze ruch produkcyjny. Dzięki temu pierwsze zapytania nie muszą pobierać stron z dysku i baza od razu pracuje z normalną prędkością. Rozszerzenie jest częścią pakietu contrib, więc nie wymaga niczego spoza standardowej dystrybucji.
Czym różni się tryb buffer od domyślnego w pg_prewarm?
Domyślnie pg_prewarm może wczytać dane do cache systemu operacyjnego, natomiast tryb buffer wczytuje strony wprost do shared_buffers, czyli do własnego bufora bazy. Tryb buffer daje pewność, że dane są w pamięci samego PostgreSQL. Podajemy go jako drugi argument funkcji obok nazwy relacji.
Jak rozgrzewać cache automatycznie po każdym restarcie?
Włącz autoprewarm, dodając pg_prewarm do parametru shared_preload_libraries i restartując serwer. Wtedy proces w tle okresowo zapisuje listę stron aktualnie w buforze, a po starcie automatycznie je odtwarza. Nie musisz już ręcznie uruchamiać żadnej funkcji po planowym restarcie.
Jak potwierdzić, że cache został rozgrzany?
Wykonaj EXPLAIN z opcją BUFFERS na zapytaniu do rozgrzanej tabeli tuż po starcie. Jeśli dominuje shared hit, a shared read jest bliskie zera, dane są już w pamięci. Sama funkcja pg_prewarm dodatkowo zwraca liczbę wczytanych bloków, więc od razu widzisz, ile stron trafiło do bufora.

Komentarze (0)

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

Brak komentarzy...