Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Katalog pg_wal rośnie i zapełnia dysk - dlaczego i co zrobić

W skrócie

  • Katalog pg_wal puchnie do dziesiątek gigabajtów i grozi zapełnieniem dysku, choć baza z pozoru pracuje normalnie.
  • PostgreSQL nie może usunąć plików WAL, bo coś je trzyma: nieaktywny slot replikacji, niewykonana archiwizacja (archive_command) albo zbyt duże okno checkpointów.
  • Ustal, co blokuje kasowanie WAL - slot, archiwizacja czy konfiguracja - usuń przyczynę, a nigdy nie kasuj plików WAL ręcznie z katalogu.

Rosnący pg_wal to częsty alarm, który łatwo źle rozwiązać. Kusi, żeby po prostu usunąć pliki z katalogu - to najszybsza droga do uszkodzenia bazy. Prawdziwe rozwiązanie polega na znalezieniu tego, co trzyma WAL. Pokazujemy trzy najczęstsze przyczyny i sposób na każdą.

Jak to wygląda w praktyce

Monitoring zgłasza malejące wolne miejsce na wolumenie z pg_wal. Liczba plików segmentów (domyślnie po 16 MB każdy) rośnie z godziny na godzinę. W logu przy problemach z archiwizacją pojawiają się komunikaty archive command failed. Rozmiar katalogu policzysz z systemu operacyjnego albo pośrednio przez SELECT count(*) FROM pg_ls_waldir();. Jeśli winny jest slot replikacji, pg_replication_slots pokaże dużą wartość zaległości.

Dlaczego tak się dzieje

WAL (Write-Ahead Log) to dziennik zmian, który PostgreSQL zapisuje przed modyfikacją danych. Segmenty WAL są recyklingowane po checkpoincie - ale tylko te, których już nikt nie potrzebuje. Są trzy typowe powody, dla których baza nie może ich zwolnić.

Pierwszy: nieaktywny slot replikacji. Slot gwarantuje replice, że primary zachowa dla niej WAL. Jeśli replika odpadła, a slot został, primary trzyma WAL w nieskończoność, czekając na powrót repliki. Drugi: archiwizacja ciągła. Gdy archive_mode = on, a archive_command zawodzi (np. brak miejsca w repozytorium kopii), PostgreSQL nie skasuje segmentu, który nie został jeszcze zarchiwizowany. Trzeci: konfiguracja - duże max_wal_size i rzadkie checkpointy sprawiają, że między checkpointami naturalnie gromadzi się sporo WAL.

Jak to rozwiązać krok po kroku

  1. Sprawdź sloty replikacji, bo to najczęstsza przyczyna: SELECT slot_name, active, wal_status, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS zaleglosc FROM pg_replication_slots ORDER BY zaleglosc DESC;. Slot z active = false i dużą zaległością to winowajca.
  2. Jeśli slot należy do repliki, która już nie wróci, usuń go: SELECT pg_drop_replication_slot('nazwa_slotu');. PostgreSQL od razu zwolni związane z nim segmenty WAL przy najbliższym checkpoincie.
  3. Sprawdź archiwizację: SELECT last_archived_wal, last_failed_wal, last_failed_time FROM pg_stat_archiver;. Jeśli last_failed_wal jest nowszy niż last_archived_wal, archive_command zawodzi. Napraw komendę (np. dostęp do repozytorium kopii) albo tymczasowo, świadomie, ustaw archive_mode = off i zrestartuj - ale tylko jeśli rezygnujesz z PITR.
  4. Wymuś checkpoint, aby baza mogła zrecyklingować zbędne już segmenty: CHECKPOINT;. Po nim niepotrzebne pliki WAL zostaną usunięte lub przeznaczone do ponownego użycia.
  5. Jeśli przyczyna jest konfiguracyjna, dostosuj rozmiary: w postgresql.conf ustaw sensowne max_wal_size (np. do rozmiaru, który mieści się na dysku z zapasem) i wykonaj SELECT pg_reload_conf();. Zbyt małe max_wal_size wywoła z kolei zbyt częste checkpointy.
  6. Nigdy nie usuwaj plików z katalogu pg_wal ręcznie. Ręczne kasowanie segmentu, który jest jeszcze potrzebny, prowadzi do uszkodzenia bazy i braku możliwości recovery. Zawsze działaj przez usunięcie slotu, naprawę archiwizacji albo CHECKPOINT.

Jak sprawdzić, że zadziałało

Po usunięciu przyczyny i wykonaniu CHECKPOINT; sprawdź, czy liczba plików spada: SELECT count(*) FROM pg_ls_waldir(); - powinna wrócić w okolice wartości wynikającej z max_wal_size. Wolne miejsce na wolumenie powinno rosnąć. Jeśli winny był slot, potwierdź, że zniknął z pg_replication_slots. Jeśli archiwizacja, sprawdź w pg_stat_archiver, że last_archived_wal znów się przesuwa, a last_failed_time nie jest już świeży.

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

Czy można usunąć pliki z katalogu pg_wal ręcznie, gdy zapełniają dysk?
Nie, nigdy. Ręczne kasowanie segmentu WAL, który jest jeszcze potrzebny do recovery, uszkadza bazę. Zamiast tego usuń nieaktywny slot replikacji, napraw archiwizację albo wymuś CHECKPOINT, aby baza sama zwolniła zbędne pliki.
Dlaczego nieaktywny slot replikacji zapełnia pg_wal?
Slot gwarantuje replice, że primary zachowa dla niej wszystkie segmenty WAL. Jeśli replika odpadła, a slot pozostał, primary trzyma WAL w nieskończoność, przez co katalog pg_wal rośnie bez ograniczeń, aż zapełni dysk.
Jak sprawdzić, który slot replikacji trzyma najwięcej WAL?
Odpytaj widok pg_replication_slots i policz różnicę między pg_current_wal_lsn a restart_lsn dla każdego slotu przez pg_wal_lsn_diff. Slot z wartością active równą false i dużą zaległością to najczęstszy winowajca.
Co zrobić, gdy archive_command zawodzi i WAL się gromadzi?
Sprawdź w pg_stat_archiver kolumny last_failed_wal i last_failed_time, potem napraw przyczynę błędu archiwizacji, na przykład dostęp lub miejsce w repozytorium kopii. Dopiero po udanej archiwizacji baza skasuje zaległe segmenty.

Komentarze (0)

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

Brak komentarzy...