Ответ
В продакшн-среде с PostgreSQL я настраиваю отказоустойчивую стратегию бэкапов, основанную на комбинации логических дампов и непрерывного архивирования WAL (Write-Ahead Log). Это позволяет восстановить базу на любой момент времени (Point-in-Time Recovery - PITR).
1. Базовая настройка в postgresql.conf:
# Уровень детализации WAL должен быть как минимум 'replica' для архивации
wal_level = replica
# Включаем режим архивации
archive_mode = on
# Команда, которая будет выполняться для архивации сегмента WAL.
# Важно, чтобы команда возвращала 0 только в случае успеха.
archive_command = 'test ! -f /mnt/backup/wal_archive/%f && cp %p /mnt/backup/wal_archive/%f'
# Пример с использованием утилиты pg_archivecleanup для ротации:
# archive_command = 'pg_archivecleanup /mnt/backup/wal_archive %r 2>/dev/null || true && cp %p /mnt/backup/wal_archive/%f'
# Рекомендуется для ускорения PITR
full_page_writes = on
После изменения конфигурации требуется перезагрузка сервиса PostgreSQL.
2. Создание базовых (полных) бэкапов:
Я использую pg_basebackup для создания физической копии кластера. Это быстрее, чем логический дамп, и является основой для PITR.
# Пример создания базового бэкапа с использованием слотов репликации для контроля задержки
pg_basebackup -D /mnt/backup/base_backup_$(date +%Y%m%d)
-U replicator -v -P
--wal-method=stream
--write-recovery-conf
--slot=backup_slot
Эту операцию можно выполнять регулярно (например, раз в неделю) без остановки основной БД.
3. Автоматизация и мониторинг:
Я создаю скрипт для бэкапа и настраиваю его выполнение через cron или системный таймер. Критически важно регулярно тестировать восстановление.
#!/bin/bash
# Скрипт /usr/local/bin/pg_backup.sh
BACKUP_DIR="/mnt/backup"
DATE=$(date +%Y%m%d_%H%M%S)
# 1. Создаём базовый бэкап
pg_basebackup -D $BACKUP_DIR/base_$DATE -U backup_user -v -P --wal-method=stream
# 2. Принудительно создаём контрольную точку и архивируем текущий WAL
psql -U backup_user -d postgres -c "SELECT pg_switch_wal();"
# 3. Очищаем старые бэкапы (храним 7 последних базовых копий)
find $BACKUP_DIR/base_* -maxdepth 0 -type d -mtime +7 -exec rm -rf {} ;
# 4. Проверяем целостность архива WAL (упрощённо)
if [ -z "$(ls -A $BACKUP_DIR/wal_archive/)" ]; then
echo "WARNING: WAL archive directory is empty!" | mail -s "PostgreSQL Backup Alert" admin@example.com
fi
4. Восстановление до точки во времени:
Для восстановления копируем базовый бэкап в PGDATA, создаём файл recovery.signal и настраиваем postgresql.conf для восстановления из архива WAL до нужного времени.
# В postgresql.conf восстанавливаемой инстанции
restore_command = 'cp /mnt/backup/wal_archive/%f %p'
recovery_target_time = '2023-10-26 15:30:00 UTC'
Такой подход, развёрнутый с помощью конфигурационного менеджмента (Ansible), обеспечивает надёжное восстановление данных.