Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Jak skonfigurować ciągłą archiwizację WAL (archive_command)

W skrócie

  • Sam dump raz na dobę nie wystarcza - po awarii chcesz odtworzyć bazę do stanu sprzed minuty, a nie sprzed wielu godzin.
  • Bez ciągłej archiwizacji WAL nie masz z czego odtworzyć zmian między backupami pełnymi, więc tracisz wszystko, co wydarzyło się po ostatniej kopii.
  • Rozwiązaniem jest włączenie archive_mode i ustawienie archive_command, które kopiuje każdy zamknięty segment WAL w bezpieczne miejsce - to fundament odtwarzania do punktu w czasie (PITR).

Ciągła archiwizacja WAL to różnica między "straciliśmy dane z całego dnia" a "odtworzyliśmy bazę do stanu sprzed dwóch minut". Pokażemy Ci, jak poprawnie skonfigurować archive_command, tak by żaden segment nie przepadł i by baza nie zapchała sobie dysku, gdy archiwizacja przestanie działać.

Jak to wygląda w praktyce

Masz nocny pg_dump i wydaje Ci się, że jesteś zabezpieczony - do momentu, gdy o 15:00 pada dysk i orientujesz się, że stracisz wszystko od północy. Backup logiczny to zdjęcie z jednej chwili; nie pozwala odtworzyć zmian, które nastąpiły później. Innym razem masz już włączoną archiwizację, ale archive_command po cichu zwraca błąd (brak miejsca w celu, zła ścieżka, wygasłe uprawnienia) - PostgreSQL nie usuwa wtedy segmentów WAL i katalog pg_wal zaczyna puchnąć, aż zapełni dysk. Oba objawy mają wspólny mianownik: archiwizacja albo nie jest włączona, albo działa nierzetelnie.

Dlaczego tak się dzieje

PostgreSQL zapisuje każdą zmianę najpierw do dziennika WAL, w segmentach po 16 MB. Domyślnie po zamknięciu segmentu jest on poddawany recyklingowi - nadpisywany. Ciągła archiwizacja polega na tym, że przed nadpisaniem serwer wywołuje archive_command: polecenie systemowe, które ma skopiować dany segment w trwałe miejsce (dysk sieciowy, magazyn obiektowy, inny serwer). Kluczowa zasada jest taka: PostgreSQL uzna segment za zarchiwizowany tylko wtedy, gdy komenda zwróci kod wyjścia 0. Jeśli komenda się nie powiedzie, serwer ponawia ją i celowo nie usuwa segmentu - dzięki temu nic nie przepada, ale kosztem rosnącego pg_wal. Zarchiwizowane segmenty razem z jednym backupem bazowym pozwalają odtworzyć bazę do dowolnego punktu w czasie (PITR).

Jak to rozwiązać krok po kroku

  1. Przygotuj cel archiwizacji - katalog na osobnym, trwałym nośniku (najlepiej innym serwerze lub magazynie), z prawami zapisu dla użytkownika, na którym działa PostgreSQL. Trzymanie archiwum na tym samym dysku co baza nie chroni przed awarią tego dysku.
  2. Włącz tryb archiwizacji: ALTER SYSTEM SET archive_mode = on;. Ten parametr wymaga restartu serwera, więc zaplanuj go w oknie serwisowym.
  3. Ustaw komendę archiwizującą. W archive_command %p to pełna ścieżka do segmentu, a %f to sama nazwa pliku. Bezpieczny wzorzec sprawdza najpierw, czy plik już nie istnieje w celu: ALTER SYSTEM SET archive_command = 'test ! -f /archiwum/%f && cp %p /archiwum/%f';. Ten warunek zapobiega nadpisaniu wcześniej zarchiwizowanego segmentu.
  4. Rozważ wymuszanie regularnej rotacji, żeby po cichszych okresach archiwum nie miało luk czasowych: ALTER SYSTEM SET archive_timeout = '60s'; zamyka i archiwizuje segment nie rzadziej niż co minutę.
  5. Zastosuj zmiany. Po ustawieniu archive_command wystarczy SELECT pg_reload_conf();, ale samo włączenie archive_mode wymaga restartu - wykonaj go teraz.
  6. Wykonaj bazowy backup jako punkt startowy dla PITR: pg_basebackup -D /kopia_bazowa -Ft -X stream. Bez backupu bazowego same segmenty WAL nie wystarczą do odtworzenia.
  7. Zabezpiecz przed zapchaniem dysku: ustaw max_slot_wal_keep_size i monitoruj pg_stat_archiver. Gdy archiwizacja zacznie się wywalać, chcesz o tym wiedzieć, zanim pg_wal zapełni partycję.

Jak sprawdzić, że zadziałało

Podstawowy dowód daje widok statystyk archiwizera: SELECT archived_count, last_archived_wal, last_archived_time, failed_count, last_failed_time FROM pg_stat_archiver;. Rosnący archived_count i świeży last_archived_time oznaczają, że segmenty faktycznie lądują w archiwum, a failed_count równy zeru - że komenda nie zwraca błędów. Wymuś zamknięcie segmentu przez SELECT pg_switch_wal(); i sprawdź, czy w katalogu docelowym pojawił się nowy plik - to potwierdza, że archive_command naprawdę kopiuje dane. Najmocniejszy test to jednak próbne odtworzenie do punktu w czasie na osobnej maszynie: z backupu bazowego plus zarchiwizowanych segmentów odtwórz bazę i sprawdź, że dane zgadzają się ze wskazaną chwilą. Backupu, którego nie przetestowałeś przez odtworzenie, nie traktuj jak backupu.

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

Po co włączać ciągłą archiwizację WAL, skoro mam nocny pg_dump?
Bo dump to zdjęcie z jednej chwili i nie pozwala odtworzyć zmian, które nastąpiły po nim. Bez ciągłej archiwizacji WAL po awarii tracisz wszystko od ostatniej pełnej kopii. Archiwizacja segmentów WAL razem z backupem bazowym umożliwia odtwarzanie do dowolnego punktu w czasie, czyli PITR, ograniczając utratę danych do minut.
Co oznaczają %p i %f w archive_command?
W archive_command %p to pełna ścieżka do archiwizowanego segmentu WAL, a %f to sama nazwa pliku. Bezpieczny wzorzec komendy najpierw sprawdza, czy plik już nie istnieje w celu, a dopiero potem go kopiuje, na przykład test wykluczający istnienie pliku połączony z cp. Warunek ten zapobiega nadpisaniu wcześniej zarchiwizowanego segmentu.
Czy włączenie archiwizacji wymaga restartu serwera?
Włączenie samego archive_mode wymaga restartu serwera, więc zaplanuj je w oknie serwisowym. Natomiast zmianę samej komendy archive_command można zastosować bez restartu, przeładowując konfigurację przez SELECT pg_reload_conf(). Dlatego tryb archiwizacji ustawia się raz, a komendę można potem dostrajać w locie.
Jak sprawdzić, że archiwizacja naprawdę działa?
Zajrzyj do widoku pg_stat_archiver: rosnący archived_count i świeży last_archived_time potwierdzają, że segmenty lądują w archiwum, a failed_count równy zeru, że komenda nie zwraca błędów. Możesz też wymusić zamknięcie segmentu przez SELECT pg_switch_wal() i sprawdzić, czy w katalogu docelowym pojawił się nowy plik. Najmocniejszym testem jest próbne odtworzenie do punktu w czasie.

Komentarze (0)

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

Brak komentarzy...