Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
Point-in-time recovery - jak odtworzyć bazę do konkretnej chwili
Point-in-time recovery (PITR, odtwarzanie do punktu w czasie) to funkcja, która ratuje bazę wtedy, gdy zwykły backup to za mało. Pokazujemy, jak przygotować archiwizację WAL i jak cofnąć klaster dokładnie do sekundy sprzed feralnej operacji.
Sytuacja jest zawsze podobna. O 14:32 ktoś uruchomił na produkcji DELETE FROM zamowienia bez klauzuli WHERE albo migracja usunęła kolumnę, której nie powinna. Zauważamy to pół godziny później. Mamy nocny backup bazowy z 02:00, ale przywrócenie go oznacza utratę całego dnia pracy. Chcielibyśmy stanu z 14:31:59 - minutę przed katastrofą. Zwykłe przywrócenie kopii bazowej tego nie da, bo ta kopia zna tylko stan z 02:00. Cała reszta dnia jest zapisana w plikach WAL (write-ahead log, dziennik zmian) i to z nich odtwarzamy brakujące godziny.
PostgreSQL każdą zmianę danych zapisuje najpierw do dziennika WAL, a dopiero potem trafia ona do właściwych plików tabel. Ten dziennik to strumień, który opisuje historię bazy krok po kroku. Kopia bazowa (wykonana przez pg_basebackup) to zamrożony obraz plików z jednej chwili. Jeśli chcemy odtworzyć bazę do dowolnego późniejszego momentu, musimy wziąć ten obraz i dograć do niego kolejne wpisy z WAL aż do wybranego punktu. Warunek jest jeden: pliki WAL z okresu od backupu do awarii muszą być bezpiecznie zarchiwizowane. Domyślnie PostgreSQL po pewnym czasie kasuje stare segmenty WAL, więc bez wcześniej włączonej archiwizacji ciągłej PITR jest niemożliwy - nie da się go włączyć wstecz.
postgresql.conf ustawiamy wal_level = replica (domyślne), archive_mode = on oraz archive_command, na przykład kopiujące segment do bezpiecznego katalogu: archive_command = 'test ! -f /archiwum/wal/%f && cp %p /archiwum/wal/%f'. Restartujemy klaster.pg_basebackup -D /backup/baza -Fp -Xs -P. To ona jest punktem startowym każdego odtworzenia.recovery.signal. Jego obecność mówi PostgreSQL, że po starcie ma wejść w tryb odtwarzania, a nie normalnie wstać.postgresql.conf ustawiamy restore_command = 'cp /archiwum/wal/%f %p' (skąd brać archiwalne segmenty) oraz cel odtwarzania: recovery_target_time = '2026-09-28 14:31:59'. Zamiast czasu możemy podać recovery_target_xid (numer transakcji) albo recovery_target_name, jeśli wcześniej oznaczyliśmy punkt przez pg_create_restore_point.SELECT pg_wal_replay_resume() lub ustawiając recovery_target_action = 'promote' przed startem. Domyślnie serwer po osiągnięciu celu pauzuje, żebyśmy zdążyli sprawdzić dane.Po starcie w logu klastra zobaczymy wpisy typu recovery stopping before commit of transaction oraz last completed transaction was at log time 2026-09-28 14:31:.... To potwierdza, do jakiej chwili doszło odtwarzanie. Następnie łączymy się psql i sprawdzamy dane - odpytujemy usuniętą tabelę i liczymy wiersze, których miało brakować. Stan odtwarzania podejrzymy zapytaniem SELECT pg_is_in_recovery(): dopóki zwraca true, baza jest w trybie odtwarzania (tylko odczyt). Po promocji zwróci false. Dobrze jest też wykonać świeżą kopię bazową odtworzonego klastra, bo po PITR linia czasu WAL się zmienia i stare archiwum nie jest już w pełni spójne z nową bazą.
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...