Будни ИТишника заметки о Linux и инфраструктуре

Бэкап PostgreSQL без плясок: pg_dump, ротация, проверка

03.08.2026 · postgres, бэкапы

Самая частая ошибка с бэкапами — считать их сделанными, пока не попробовал восстановить. Всё остальное решается десятком строк скрипта.

Дамп

pg_dump -Fc -Z6 -h 127.0.0.1 -U postgres mydb \
  -f /var/backups/pg/mydb-$(date +%F).dump

Формат -Fc (custom) сжимается и восстанавливается через pg_restore, позволяя вытащить отдельную таблицу. Для баз больше пары десятков гигабайт это уже не вариант — там нужен pg_basebackup или WAL-архивирование, но для типовой базы на 5–10 ГБ custom-дамп закрывает вопрос.

Ротация

Проще всего не изобретать своё, а удалить старое по возрасту:

find /var/backups/pg -name '*.dump' -type f -mtime +14 -delete

Правило простое: ретеншн должен быть длиннее, чем время, за которое вы замечаете проблему. Две недели — разумный минимум, месяц — спокойнее.

Проверка, без которой всё бессмысленно

Раз в неделю дамп восстанавливается во временную базу на том же сервере. Если pg_restore упал — узнаём об этом в понедельник, а не в момент аварии.

createdb -h 127.0.0.1 -U postgres restore_test
pg_restore -h 127.0.0.1 -U postgres -d restore_test --no-owner \
  /var/backups/pg/mydb-$(date +%F).dump
psql -h 127.0.0.1 -U postgres -d restore_test -c '\dt' | tail -5
dropdb -h 127.0.0.1 -U postgres restore_test

Мелочи, которые спасают

  • Пароль не в командной строке: ~/.pgpass с правами 600 или PGPASSWORD из файла окружения юнита.
  • Код возврата проверять обязательно: set -e в скрипте и Type=oneshot в systemd-юните. Молча упавший pg_dump оставляет пустой файл, и ротация его бережно сохранит.
  • Бэкап на том же диске — не бэкап. Минимум — другой хост, лучше — другая площадка.
  • gzip -t на архиве перед ротацией: ловит обрезанные файлы почти бесплатно.