← Назад к вопросам

Как восстанавливал PostgreSQL из бэкапа

2.0 Middle🔥 142 комментариев
#Базы данных

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Восстановление PostgreSQL из бэкапа: практический опыт

Восстановление PostgreSQL из резервной копии — критическая процедура, которую я выполнял в различных сценариях: от плановых миграций до аварийных ситуаций после инцидентов с потерей данных. Подход зависит от типа бэкапа, требований к времени восстановления (RTO) и целостности данных (RPO). Я использую комбинацию инструментов и методик.

Основные типы бэкапов и методы восстановления

1. Логические бэкапы с помощью pg_dump / pg_dumpall

Наиболее распространённый метод для резервирования отдельных баз или всего кластера. Восстановление зависит от формата дампа.

Восстановление из plain-формата (SQL):

# Для восстановления всей базы
psql -U postgres -d mydb -f backup.sql

# Для восстановления в чистую базу
createdb mydb_restored
psql -U postgres -d mydb_restored < backup.sql

Восстановление из custom-формата (сжатый, с возможностью выборочного восстановления):

# Восстановление всей базы
pg_restore -U postgres -d mydb -j 4 backup.dump

# Выборочное восстановление только схемы
pg_restore -U postgres -d mydb --schema-only backup.dump

# Восстановление с созданием новой базы
pg_restore -U postgres -C -d postgres -j 8 backup.dump

Ключевые параметры pg_restore:

  • -j или --jobs — параллельное восстановление (ускоряет процесс для больших БД)
  • -C — создание базы данных перед восстановлением
  • --section=pre-data/data/post-data — контроль этапов восстановления
  • -l и -L — список и выбор объектов для восстановления

2. Физические бэкапы через файловую систему

Для полного PITR (Point-in-Time Recovery) использую WAL-архивирование в комбинации с base backup.

Процедура полного восстановления на определённый момент времени:

# 1. Останавливаем PostgreSQL, если он запущен
sudo systemctl stop postgresql-15

# 2. Очищаем каталог данных (или перемещаем в backup)
mv /var/lib/pgsql/15/data /var/lib/pgsql/15/data_old

# 3. Восстанавливаем base backup
tar -xzf base_backup.tar.gz -C /var/lib/pgsql/15/data

# 4. Настраиваем recovery.spec (ранее recovery.conf)
cat > /var/lib/pgsql/15/data/recovery.spec << EOF
restore_command = 'cp /wal_archive/%f %p'
recovery_target_time = '2024-01-15 14:30:00'
recovery_target_action = promote
EOF

# 5. Устанавливаем правильные права
chown -R postgres:postgres /var/lib/pgsql/15/data

# 6. Запускаем PostgreSQL
sudo systemctl start postgresql-15

3. Восстановление с использованием Barman и pgBackRest

Для продакшн-среды предпочитаю использовать специализированные инструменты.

Пример восстановления с помощью Barman:

# Проверяем доступные бэкапы
barman list-backup main-server

# Восстанавливаем последний бэкап
barman recover --target-time "2024-01-15 14:30:00" \
               main-server latest \
               /var/lib/pgsql/15/data_restored

# Или напрямую в работающий сервер (с replication)
barman recover --remote-ssh-command "ssh postgres@standby" \
               main-server latest \
               /var/lib/pgsql/data

Пример с pgBackRest:

# Восстановление полного бэкапа
pgbackrest restore --stanza=mydb \
                   --type=time \
                   --target="2024-01-15 14:30:00" \
                   --target-action=promote

# Ускоренное восстановление delta (только изменённые файлы)
pgbackrest restore --stanza=mydb --delta

Критические аспекты и best practices

  1. Проверка целостности бэкапов:

    • Всегда проверяю контрольные суммы после создания бэкапа
    • Регулярно выполняю пробные восстановления на тестовых стендах
    • Использую pg_verifybackup для проверки физических бэкапов
  2. Оптимизация времени восстановления:

    • Настройка parallel restore через -j параметр
    • Использование tablespace mapping при переносе между серверами
    • Предварительное создание индексов после загрузки данных
  3. Восстановление части данных:

    # Восстановление только одной таблицы
    pg_restore -U postgres -d mydb -t my_table backup.dump
    
    # Восстановление исключая определённые таблицы
    pg_restore -U postgres -d mydb -T excluded_table backup.dump
    
  4. Обработка больших баз данных:

    • Использую секционирование для ускорения восстановления фрагментов
    • Применяю partial restore для критичных данных в первую очередь
    • Настраиваю maintenance_work_mem и max_wal_size для операции восстановления

Автоматизация и мониторинг

Я выстраиваю процесс восстановления как часть Infrastructure as Code:

  • Ansible-роли для автоматического развёртывания и восстановления
  • Скрипты валидации восстановленных данных
  • Интеграция с системами мониторинга (Prometheus alerts при проблемах с бэкапами)
  • Регулярные fire-drill упражнения для команды

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

#!/bin/bash
# validate_restore.sh
RESTORED_DB="mydb_restored"
CHECK_QUERY="SELECT COUNT(*) FROM critical_table;"

if psql -U postgres -d "$RESTORED_DB" -c "$CHECK_QUERY" | grep -q "12345"; then
    echo "✓ Восстановление прошло успешно"
    exit 0
else
    echo "✗ Ошибка восстановления: данные не соответствуют ожидаемым"
    exit 1
fi

Восстановление — это не просто техническая процедура, а комплексный процесс, включающий документацию, тестирование и регулярные тренировки команды. Самый дорогой бэкап — тот, который не может быть восстановлен в нужный момент.

Как восстанавливал PostgreSQL из бэкапа | PrepBro