Перейти к содержанию
Innovialabs

Восстановление PostgreSQL на момент времени (PITR) через WAL

Продвинутое3 мин

Коротко

PITR восстанавливает базовый бэкап и проигрывает архивные WAL-файлы до выбранного момента, поэтому базу можно вернуть на секунду до ошибочного DELETE; для этого нужна непрерывная архивация WAL и регулярные тестовые восстановления.

Коротко

PostgreSQL записывает каждое изменение в журнал предзаписи (WAL) до того, как применить его к файлам данных. Если у вас есть:

  1. базовый бэкап (физическая копия каталога данных) и
  2. все сегменты WAL, созданные после этого бэкапа,

можно восстановить бэкап и проиграть WAL до любого выбранного момента. Это и есть восстановление на момент времени (PITR). Ночной pg_dump так не умеет: он возвращает только к моменту дампа.

Писать скрипты для archive_command вручную ненадёжно, поэтому обычно используют pgBackRest или WAL-G. Оба берут на себя сжатие, хранение по политике retention, параллельность и работу с локальным репозиторием или объектным хранилищем вроде S3.

Настройка pgBackRest

Конфигурация PostgreSQL (postgresql.conf):

wal_level = replica
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'

Для archive_mode нужен перезапуск. Затем конфиг pgBackRest (/etc/pgbackrest/pgbackrest.conf):

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2

[main]
pg1-path=/var/lib/postgresql/data

Инициализируйте, проверьте и сделайте первый полный бэкап:

pgbackrest --stanza=main stanza-create
pgbackrest --stanza=main check
pgbackrest --stanza=main --type=full backup

Запускайте бэкапы по расписанию через cron или systemd timer, например полный раз в неделю и дифференциальный ежедневно (--type=diff). Храните репозиторий на другой машине или в объектном хранилище: бэкап на том же диске погибнет вместе с сервером.

Альтернатива: WAL-G

WAL-G настраивается через переменные окружения (префикс хранилища, ключи доступа, сжатие) и хорошо работает с облачными хранилищами:

archive_command = 'wal-g wal-push %p'
wal-g backup-push "$PGDATA"

Выбор в основном про эксплуатацию: у pgBackRest богатая проверка целостности и режим локального репозитория, WAL-G лёгкий и ориентирован на облако. PITR поддерживают оба.

Восстановление после случайного удаления

Допустим, кто-то выполнил DELETE FROM orders без WHERE около 14:30.

1. Определите целевое время. Используйте логи приложения, лог PostgreSQL (если log_statement это фиксирует) или pg_waldump, чтобы найти транзакцию. Выберите момент прямо перед удалением. Если известен ID транзакции или LSN, точнее будут recovery_target_xid или recovery_target_lsn.

2. Лучше восстанавливать на отдельный сервер. Тогда потерянные строки можно перенести обратно в продакшен, не откатывая всё остальное, что произошло после 14:30.

3. Восстановление через pgBackRest:

sudo systemctl stop postgresql
pgbackrest --stanza=main --delta \
  --type=time "--target=2026-10-10 14:29:00+05" \
  --target-action=promote restore
sudo systemctl start postgresql

pgBackRest сам прописывает параметры восстановления. С WAL-G вы скачиваете бэкап и задаёте их вручную:

wal-g backup-fetch "$PGDATA" LATEST
touch "$PGDATA/recovery.signal"
restore_command = 'wal-g wal-fetch %f %p'
recovery_target_time = '2026-10-10 14:29:00+05'
recovery_target_action = 'promote'

4. Проверьте результат, прежде чем куда-то его переносить: количество строк, последние записи до инцидента, смоук-тесты приложения. Если момент выбран неудачно, восстановите заново с другой целью.

После восстановления PostgreSQL начинает новую линию времени (timeline). Вскоре сделайте свежий полный бэкап.

Как тестировать процедуру

Бэкап, который вы ни разу не восстанавливали, — это надежда, а не бэкап. Сделайте проверку рутиной:

  • Восстанавливайте на отдельный сервер по расписанию, а не только во время инцидентов.
  • Запускайте pgbackrest check или следите за pg_stat_archiver на предмет неудачных попыток архивации.
  • Настройте алерт на отставание или сбой архивации: диск, забитый неархивированными WAL, может остановить основной сервер.
  • Замерьте, сколько длится восстановление. Это ваше реальное время восстановления, и оно растёт с объёмом данных и количеством WAL для проигрывания.
  • Напишите короткий runbook с точными командами, чтобы в стрессе восстановление сводилось к копированию.

Частые ошибки

  • Хранить бэкапы на том же сервере или диске, что и базу.
  • Включить архивацию и ни разу не проверить, что она проходит.
  • Слишком короткий retention, который не покрывает период, когда ошибки обычно замечают.
  • Восстанавливать прямо поверх продакшена и терять легитимные изменения после инцидента.
  • Забывать про часовой пояс в целевом времени.

Частые вопросы

Он полезен для логических копий, переездов и небольших баз, но восстанавливает только на момент дампа. Для восстановления на произвольную точку нужны базовые бэкапы плюс архивация WAL.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.