opsjournal.net

Бэкапы PostgreSQL через pgBackRest: с нуля до восстановления

· postgresqlбэкапы

Долго жил с pg_dump по крону и считал, что бэкапы у меня есть. Ровно до момента, когда понадобилось восстановить базу на состояние «час назад», а не «прошлая ночь». Дамп так не умеет, нужен архив WAL. Перебрал варианты и остановился на pgBackRest: он один пакет, понятно настраивается и умеет проверять сам себя.

Что получилось в итоге

Конфигурация

Весь конфиг помещается в один файл /etc/pgbackrest/pgbackrest.conf:

[global]
repo1-path=/backup/pgbackrest
repo1-retention-full=4
repo1-retention-diff=7
compress-type=zst
process-max=2
start-fast=y

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

В postgresql.conf включаем архивирование:

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

После перезапуска PostgreSQL создаём stanza и сразу проверяем, что архив доходит до репозитория:

sudo -u postgres pgbackrest --stanza=main stanza-create
sudo -u postgres pgbackrest --stanza=main check

Если check висит больше минуты, почти наверняка не работает archive_command. Смотрите лог PostgreSQL, а не pgBackRest: ошибка будет там.

Расписание

Я использую systemd timers (почему, писал отдельно), но с cron тоже всё просто:

30 2 * * 0   postgres  pgbackrest --stanza=main --type=full backup
30 2 * * 1-6 postgres  pgbackrest --stanza=main --type=diff backup

Восстановление — то, ради чего всё затевалось

Бэкап, из которого ни разу не восстанавливались, это надежда, а не бэкап. Восстановление на момент времени:

systemctl stop postgresql
sudo -u postgres pgbackrest --stanza=main --delta \
  --type=time "--target=2025-03-14 11:20:00+03" restore
systemctl start postgresql

--delta экономит время: pgBackRest сравнивает файлы по контрольным суммам и перезаписывает только изменившиеся. На базе в 40 ГБ это разница между сорока минутами и пятью.

Чего я не ожидал

Через полгода эксплуатации: два реальных восстановления, оба прошли спокойно. Ради этого стоило потратить вечер.