PostgreSQLSeniorSystem design
Что такое PITR (point-in-time recovery)? Как её настроить? Что такое base backup + WAL archive?
PITR восстанавливает кластер на произвольный момент: берут base backup (pg_basebackup или pgBackRest), непрерывно архивируют WAL (archive_command → S3), при восстановлении задают recovery_target_time и replay-ят архив через restore_command.
Что такое PITR
Point-in-time recovery (PITR) — механизм восстановления кластера PostgreSQL на произвольный момент времени в прошлом. Основан на двух компонентах: base backup (физический снимок кластера) и WAL archive (непрерывная цепочка журнальных сегментов от момента backup до целевого времени).
Как работает
- Делается base backup — согласованный снимок всего $PGDATA.
- WAL-сегменты непрерывно архивируются (в S3, GCS, на NFS) с момента backup и далее.
- При восстановлении PostgreSQL стартует из base backup, затем replay-ит WAL-сегменты до указанного
recovery_target_time, LSN, имени restore point или transaction id. - После достижения цели кластер открывается как новая timeline.
Настройка шаг за шагом
1. postgresql.conf — включить архивирование:
# postgresql.conf
archive_mode = on
archive_command = 'aws s3 cp %p s3://my-bucket/wal/%f'
# Или через pgBackRest:
# archive_command = 'pgbackrest --stanza=main archive-push %p'
wal_level = replica # минимум для архива
2. Снять base backup:
# Встроенный pg_basebackup
pg_basebackup -h localhost -U replicator -D /backup/base \
-Ft -Xs -P --gzip
# Или pgBackRest (рекомендуется для production):
pgbackrest --stanza=main backup --type=full
3. Восстановление на конкретный момент:
# Остановить кластер, очистить PGDATA, восстановить base backup
rm -rf /var/lib/postgresql/17/main/*
tar xzf /backup/base/base.tar.gz -C /var/lib/postgresql/17/main/
# Создать recovery signal
touch /var/lib/postgresql/17/main/recovery.signal
# postgresql.conf или postgresql.auto.conf:
restore_command = 'aws s3 cp s3://my-bucket/wal/%f %p'
recovery_target_time = '2026-05-18 14:30:00+00'
recovery_target_action = 'promote' # promote | pause | shutdown
4. Запустить PostgreSQL — он сам replay-ит WAL и откроется.
Мониторинг архива
-- Последний успешно заархивированный WAL:
SELECT last_archived_wal, last_archived_time,
last_failed_wal, last_failed_time,
archived_count, failed_count
FROM pg_stat_archiver;
Подводные камни
- Разрыв в WAL archive (потерянный или повреждённый сегмент) останавливает PITR раньше цели — обнаруживают только при restore drill, не в момент аварии.
- Слишком короткий retention WAL-сегментов делает старый base backup бесполезным: цепочка обрывается до момента backup.
archive_commandдолжен возвращать 0 только при успешной копии; любой non-zero вызывает повтор и задержку переключения WAL — нужен алерт наlast_failed_wal.- Восстановление на старую timeline без остановки downstream-систем (очереди, реплики) порождает рассинхронизацию и дублирование событий.
- base backup + весь WAL от момента backup до recovery_target может занимать сотни GB — нужно планировать пропускную способность сети и место на restore-хосте.
- Без регулярных автоматических restore drill (ежемесячно) нельзя быть уверенным в рабочести PITR — наличие файлов не равно восстанавливаемости.
recovery_target_action = 'pause'позволяет проверить данные перед promote, но кластер остаётся read-only; при ошибке нужен restart с другим target.
Common mistakes
- Хранить base backup без WAL archive.
- Не проверять restore.
- Путать logical dump с PITR.
What the interviewer is testing
- Просит объяснить цепочку base backup + WAL.
- Проверяет RPO/RTO.
- Уточняет recovery target и timeline.