Резервное копирование PostgreSQL — это не только pg_dump. Важно выбрать формат под задачу, настроить архивацию WAL, автоматизировать выгрузку и регулярно проверять восстановление. Разберём рабочую схему для домашнего сервера и небольшой производственной базы.

Способы копирования

Логическое копирование (pg_dump) даёт переносимый дамп между версиями. Физическое (резервные копии каталога данных через pg_basebackup) быстрее для больших баз, но привязано к версии.

# логическая копия одной базы
pg_dump -Fc -Z6 -f /backup/mydb.dump mydb
# все базы
pg_dumpall --globals-only > /backup/globals.sql
pg_dumpall > /backup/all.sql
# проверить дамп
ls -lh /backup/mydb.dump
pg_restore --list /backup/mydb.dump | head -10

Формат -Fc (custom) сжат и поддерживает частичное восстановление через pg_restore — это практичнее обычного SQL-файла.

Автоматизация через cron

#!/bin/bash
# /usr/local/bin/pg-backup.sh
set -euo pipefail
BACKUP_DIR=/backup/postgresql
DATE=$(date +%F_%H-%M)
mkdir -p "$BACKUP_DIR"
for db in $(psql -At -c "SELECT datname FROM pg_database WHERE NOT datistemplate"); do
  pg_dump -Fc -f "$BACKUP_DIR/${db}_${DATE}.dump" "$db"
done
# оставить последние 14 дней
find "$BACKUP_DIR" -name '*.dump' -mtime +14 -delete

# crontab -e
# 30 3 * * * /usr/local/bin/pg-backup.sh >> /var/log/pg-backup.log 2>&1

Переменные подключения задавайте через PGHOST, PGUSER, PGPASSWORD в защищённом файле, а не прямо в скрипте.

Архивация WAL для точного восстановления

Чтобы восстановиться не на момент дампа, а на любую секунду, включите архивацию WAL.

# postgresql.conf
# wal_level = replica
# archive_mode = on
# archive_command = 'cp %p /backup/wal/%f'

psql -c "show wal_level;"
psql -c "show archive_mode;"
ls /backup/wal | wc -l

Архивировать можно и на удалённый сервер: rsync, объектное хранилище или отдельная машина. Главное — не хранить архив на том же диске, что и база.

Проверка восстановления

Непроверенная копия не считается копией. Восстановление тестируют на изолированной машине или в контейнере.

# восстановление в отдельную базу
createdb restore_test
pg_restore -d restore_test /backup/mydb.dump
# сверка
psql -d restore_test -Atc "select count(*) from important_table"
psql -d mydb -Atc "select count(*) from important_table"
# очистка
dropdb restore_test

Планируйте проверку раз в месяц и записывайте время восстановления: оно и есть ваш реальный RTO.

Репликация как дополнение

Стандбай-реплика — не замена бэкапу, но способ сократить потерю данных до секунд при отказе основного сервера.

# на реплике
pg_basebackup -D /var/lib/postgresql/16/main -Fp -Xs -R
# в standby.signal и postgresql.auto.conf задаётся primary_conninfo
# проверить роль
psql -Atc "select pg_is_in_recovery();"

Хранение и шифрование

# сжатие уже есть в -Fc; для каталогов
tar -czf /backup/wal-$(date +%F).tar.gz /backup/wal
# шифрование архива (пример gpg)
gpg --symmetric --cipher-algo AES256 /backup/mydb.dump
# выгрузка на другой хост
rsync -av /backup/postgresql/ backup@nas:/backups/pg/

Держите минимум три копии на двух разных носителях, одна — вне площадки. И храните пароль шифрования отдельно от данных.

Мониторинг заданий

# последний запуск и его результат
tail -20 /var/log/pg-backup.log
# размер выгрузок
du -sh /backup/postgresql
# не вырос ли WAL из-за сломанного archive_command
psql -Atc "select count(*) from pg_stat_archiver;"

Остановленный архиватор — классический сценарий: база перестаёт принимать запись, потому что WAL не удаляются.

Что бэкапить кроме самих данных

Дамп базы не содержит ролей, tablespaces и части конфигурации. При восстановлении на чистый сервер это вылезет в ручную работу.

# роли и глобальные настройки
pg_dumpall --globals-only > /backup/globals.sql
# конфигурацию сервера
sudo cp -a /etc/postgresql /backup/etc-postgresql-$(date +%F)
# сертификаты и ключи, если используются TLS
sudo tar -czf /backup/pg-ssl-$(date +%F).tar.gz /var/lib/postgresql/*/main/ssl 2>/dev/null || true
# сверить состав
ls -lh /backup/

Храните рядом с копиями и версии: версию PostgreSQL, список расширений и версии пакетов. Восстановление дампа на другую мажорную версию часто требует промежуточного шага.

# версии и расширения
psql -Atc "select version();"
psql -Atc "select extname, extversion from pg_extension;"

Планирование RTO и RPO

RPO — сколько данных вы готовы потерять, RTO — сколько времени готовы восстанавливаться. От них зависит выбор метода.

  • RPO часы — достаточно ежедневного pg_dump.
  • RPO минуты — нужна архивация WAL.
  • RTO минуты — нужен готовый сервер или реплика.
# оценить фактическое окно потери данных
# дата последнего дампа
ls -l --time-style=long-iso /backup/postgresql | tail -5
# количество архивных WAL
ls /backup/wal | wc -l

Запишите выбранные значения рядом с процедурой восстановления: без них любая инструкция остаётся мнением.

Восстановление после сбоя: порядок действий

  1. Поднять чистый кластер той же версии.
  2. Восстановить роли из globals.sql.
  3. Восстановить последний дамп нужной базы.
  4. Применить архив WAL до нужного момента.
  5. Сверить критичные таблицы контрольными запросами.
  6. Переключить приложение и наблюдать за логами.
# контрольные сверки
psql -Atc "select count(*) from orders;"
psql -Atc "select max(created_at) from orders;"
# журналы после переключения
journalctl -u postgresql -b | tail -30

Типичные ошибки бэкапов

  • Задание написано, но лог пуст: ошибка авторизации, которая молча проглатывается без set -e.
  • Дампы пишутся на тот же диск, что и база, — общий отказ не переживёт ни данные, ни копии.
  • Ретеншн слишком агрессивный: старые копии удаляются раньше, чем обнаруживается порча данных.
  • Восстановление никогда не тестировалось, и объём таблицы в дампе отличается от ожидаемого.
  • Пароль от шифрования архива лежит рядом с ним же.
# убедиться, что задание реально отработало
grep -c "pg_dump" /var/log/pg-backup.log | tail -1
ls -lh --time-style=long-iso /backup/postgresql | tail -5
# сверить размеры за последние запуски — резкий обвал подозрителен
du -sh /backup/postgresql/*  2>/dev/null | tail -5

Итог

Рабочая схема: pg_dump -Fc по cron, архивация WAL, выгрузка копий на другой хост и ежемесячная проверка восстановления. Репликация сокращает потерю данных, но не заменяет бэкап. Фиксируйте RTO и RPO на практике, а не в планах.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте