Рабочие заметки

Резервные копии PostgreSQL без сюрпризов

Август 2026

Главный сюрприз в резервных копиях всегда один и тот же: копии есть, а восстановиться из них нельзя. Причём выясняется это ровно тогда, когда восстановиться нужно.

Что выбрать

pg_dumppg_basebackup
Что снимаетлогический слепок: SQL или архивфизическую копию каталога данных
Переносимостьмежду версиями и архитектурамитолько та же мажорная версия
Гранулярностьотдельная база, отдельная таблицакластер целиком
Восстановление на момент временинетда, вместе с WAL
Стоимость на большой базевысокаяумеренная

Практическое правило: пока база помещается в десятки гигабайт и требования формулируются как «не потерять больше суток», хватает pg_dump. Как только появляется требование «не потерять больше пяти минут», нужен физический бэкап с архивированием WAL, и это уже другая по сложности система.

Снятие

Формат custom, а не простой SQL: он сжат, из него можно восстановить отдельные объекты, и он умеет восстанавливаться параллельно.

pg_dump --format=custom --compress=9 \
        --file=/var/backups/pg/app-$(date +%F).dump \
        app

Отдельно стоит снимать глобальные объекты — роли и права. Их pg_dump не включает, и при восстановлении на чистый сервер это обнаруживается неприятным образом:

pg_dumpall --globals-only --file=/var/backups/pg/globals-$(date +%F).sql

Проверка восстановлением — обязательная часть

Копия, из которой ни разу не восстанавливались, копией не является. Это единственный пункт, на котором я не готов экономить, потому что все известные мне случаи потери данных упирались именно в него.

createdb restore_check
pg_restore --dbname=restore_check --jobs=4 /var/backups/pg/app-2026-08-29.dump
psql --dbname=restore_check --command='select count(*) from orders'
dropdb restore_check

Проверка должна быть автоматической и должна ругаться при провале. Ручная проверка «когда-нибудь потом» не выполняется никогда — это проверено на себе.

Хранение

Три вещи, каждая из которых однажды спасала:

Копия на другой машине. Диск, на котором лежит и база, и её резервная копия, решает ровно одну проблему — случайный DROP TABLE, и не решает отказ самого диска.

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

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