ОС: Debian 13 (Trixie)
Версия PostgreSQL: 18
Стратегия: FULL-бэкап каждую субботу, PAGE-инкремент в остальные дни.
Хранение: 4 FULL-цепочки (≈ 4 недели) с WAL для каждой.
apt install -y gpg wget
wget -qO - https://repo.postgrespro.ru/pg_probackup/keys/GPG-KEY-PG-PROBACKUP | \
tee /etc/apt/trusted.gpg.d/pg_probackup.asc
. /etc/os-release
echo "deb [arch=amd64] https://repo.postgrespro.ru/pg_probackup/deb $VERSION_CODENAME main-$VERSION_CODENAME" | \
tee /etc/apt/sources.list.d/pg_probackup.list
apt update && apt install pg-probackup-18
В реальной ситуации используйте для бекапа NFS. Нам понадобится папка бекапа и папка для логов работы бекапов.
mkdir -p /mnt/nfs/backup
chown postgres:postgres /mnt/nfs/backup
mkdir -p /var/log/pgbackup
chown postgres:postgres /var/log/pgbackup
Теперь надо инициализировать pg_probackup, указав ему созданные папки.
su - postgres
pg_probackup-18 init -B /mnt/nfs/backup
pg_probackup-18 add-instance \
-B /mnt/nfs/backup \
--instance main \
--pgdata /var/lib/postgresql/18/main
Для работы резервного копирования необходимо внести правки в postgresql.conf:
wal_level = replica
archive_mode = on
archive_timeout = 300
archive_command = 'pg_probackup-18 archive-push -B "/mnt/nfs/backup" --instance "main" --wal-file-path=%p --wal-file-name=%f --compress'
wal_level = replica— Определяет количество информации, записываемой в WAL. Уровеньreplicaпишет достаточно данных для восстановления и репликации. Это минимально необходимый уровень приarchive_mode = on.
archive_mode = on— Включает механизм архивирования WAL. Приon— каждый заполненный сегмент передаётся в archive_command перед тем как может быть удалён.
archive_timeout = 300— Принудительно переключает текущий сегмент каждые 5 минут, даже если он не заполнен. Иначе PostgreSQL будет ждать накопления определённого объёма, что на малых базах может занимать часы. Значение300гарантирует, что мы не потерям данных больше, чем за 5 минут (RPO 5 минут).
archive_command = '...'— Команда, которую PostgreSQL выполняет для каждого готового WAL-сегмента до его удаления.
pg_probackup-18 archive-push— подкоманда pg_probackup, которая принимает WAL-сегмент и кладёт его в каталог бэкапов.
-B "/mnt/nfs/backup" — путь к корневому каталогу бэкапов (backup catalog), тот же что указан во всех остальных командах pg_probackup.
--instance "main"— имя инстанса, которое мы задали при add-instance. WAL ляжет в wal/main/ внутри каталога бэкапов.
--wal-file-path=%p— %p подставляется PostgreSQL и содержит полный путь к файлу сегмента на диске, например /var/lib/postgresql/18/main/pg_wal/000000010000000000000001. Это источник — откуда взять файл.
--wal-file-name=%f—%fподставляется PostgreSQL и содержит только имя файла, например 000000010000000000000001. Это имя, под которым файл будет сохранён в архиве.
--compress— сжимать WAL-сегменты при сохранении в архив. Алгоритм берётся из set-config (настроим дальше). Экономит место.
Так же нам необходима роль в PostgreSQL для создания бекапов с набором прав (обратите внимание, для версий ниже PostgreSQL 15 запросы будут другие):
CREATE ROLE backup WITH LOGIN;
GRANT USAGE ON SCHEMA pg_catalog TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.set_config(text, text, boolean) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_backup_start(text, boolean) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_backup_stop(boolean) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_wal() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_wal_replay_lsn() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.txid_current() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_control_checkpoint() TO backup;
Добавим доверие для локального подключения в pg_hba.conf:
local all backup peer
Применим настройки, перезагрузив PostgreSQL:
systemctl restart postgresql
Проверяем архивацию WAL — в папке должны появиться файлы:
su - postgres -c "psql -c \"SELECT pg_switch_wal();\""
ls /var/lib/pgbackup/wal_archive/main/wal/
su - postgres
pg_probackup-18 set-config \
-B /mnt/nfs/backup \
--instance main \
--retention-redundancy=4 \
--wal-depth=4 \
--compress-algorithm=zlib \
--compress-level=1 \
--archive-timeout=15min \
--log-level-console=INFO \
--log-level-file=WARNING \
--log-filename=pg_probackup.log \
--error-log-filename="error-pg_probackup-%u.log" \
--log-directory=/var/log/pgbackup \
--log-rotation-age=7d
-B /mnt/nfs/backup— Путь к корневому каталогу бэкапов. Должен совпадать во всех командах pg_probackup.
--instance main— Имя инстанса, для которого сохраняется конфиг. Один каталог может хранить бэкапы нескольких инстансов с разными именами.
--retention-redundancy=4— Сколько FULL-бэкапов хранить. Когда после очередного FULL их становится 5 — самый старый удаляется вместе со всей своей цепочкой PAGE-инкрементов.
--wal-depth=4— Для скольких последних FULL-цепочек хранить WAL в архиве. Совпадает с retention-redundancy=4 — WAL хранится ровно для тех цепочек, которые ещё не удалены. WAL старше самого старого хранимого FULL удаляется.
--compress-algorithm=zlib— Алгоритм сжатия бэкапов и WAL-архива.
--compress-level=1— Уровень сжатия от 1 до 19 для zstd. Уровень 1 — минимальное сжатие, максимальная скорость. Это обеспечит разумное уменьшение объём при высокой скорости выполнения бекапа.
--archive-timeout=15min— Сколько времени pg_probackup ждёт появления нужного WAL-сегмента в архиве во время снятия бэкапа. Актуально при медленном хранилище — например NFS, где archive_command может выполняться с задержкой. Не путать с archive_timeout в postgresql.conf — это разные параметры.
--log-level-console=INFO— Уровень детализации логов в stdout. INFO — выводить все информационные сообщения. Удобно видеть прогресс при ручном запуске.
--log-level-file=WARNING— Уровень детализации логов в файл. WARNING — писать только предупреждения и ошибки. В production нет смысла хранить подробный лог каждого успешного бэкапа — только проблемы.
--log-filename=pg_probackup.log— Имя основного лог-файла для всех сообщений уровня WARNING и выше.
--error-log-filename="error-pg_probackup-%u.log"— Отдельный файл только для ошибок. %u — маска дня недели (1=пн, 7=вс), то есть создаётся 7 файлов, которые перезаписываются каждую неделю. Удобно для мониторинга — достаточно проверять один файл текущего дня.
--log-directory=/var/log/pgbackup— Каталог для всех лог-файлов pg_probackup. Вынесен отдельно от каталога бэкапов, что правильно — логи и данные не должны мешать друг другу.
--log-rotation-age=7d— Ротация лог-файлов раз в 7 дней. Без этого pg_probackup.log будет расти бесконечно. В сочетании с %u в имени файла ошибок даёт аккуратное хранение логов за неделю.
Проверяем:
pg_probackup-18 show-config -B /mnt/nfs/backup --instance main
Теперь настроим Cron для запуска полного и инкрементного бекапа:
crontab -u postgres -e
Внесём правила:
# FULL — каждую субботу в 02:00
0 2 * * 6 pg_probackup-18 backup -B /mnt/nfs/backup --instance main -b FULL --temp-slot -U backup --delete-expired --delete-wal
# PAGE — воскресенье-пятница в 02:00
0 2 * * 0,1,2,3,4,5 pg_probackup-18 backup -B /mnt/nfs/backup --instance main -b PAGE --temp-slot -U backup --delete-expired --delete-wal
0 2 * * 6— Запуск каждую субботу в 2 часа ночи.
0 2 * * 0,1,2,3,4,5— Запуск каждый день, кроме субботы, в 2 часа ночи.
-B /mnt/nfs/backup— Путь к корневому каталогу бэкапов. Должен совпадать во всех командах pg_probackup.
--instance main— Имя инстанса, для которого сохраняется конфиг. Один каталог может хранить бэкапы нескольких инстансов с разными именами.
-b FULL— Полная копия-b PAGE— Инкрементальный бэкап: сканирует WAL-архив с момента предыдущего бэкапа и сохраняет только изменённые страницы.--temp-slot— Создаёт временный replication slot на время бэкапа, чтобы PostgreSQL не удалил нужные WAL-сегменты до их получения.
-U backup— Пользователь PostgreSQL, от имени которого pg_probackup подключается к базе.--delete-expired --delete-wal— Удалить старые бекапы и старые WAL согласно политике.
Проверять сразу не имеет смысла, необходимо подождать несколько дней для создания бекапов.
# Список бэкапов и их статус
pg_probackup-18 show -B /mnt/nfs/backup --instance main
# Валидация всего каталога
pg_probackup-18 validate -B /mnt/nfs/backup --instance main
# Состояние WAL-архива
pg_probackup-18 show -B /mnt/nfs/backup --instance main --archive
systemctl stop postgresql
# Восстановить последний бэкап:
pg_probackup-18 restore \
-B /mnt/nfs/backup \
--instance main \
--pgdata=/var/lib/postgresql/18/main \
--recovery-target-action=promote
# PITR — восстановить на конкретный момент времени:
pg_probackup-18 restore \
-B /mnt/nfs/backup \
--instance main \
--pgdata=/var/lib/postgresql/18/main \
--recovery-target-time="2026-05-28 15:00:00" \
--recovery-target-action=promote
systemctl start postgresql