Резервное копирование и восстановление баз данных в Docker: PostgreSQL и MySQL | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Резервное копирование и восстановление баз данных в Docker: PostgreSQL и MySQL

05 мая 2026 8 мин. чтения

Потеря данных в Docker-контейнерах с PostgreSQL или MySQL может парализовать работу приложения. Эта статья предоставляет проверенные на практике методы резервного копирования и восстановления. Вы получите готовые команды для дампов, работы с томами и автоматизации процесса через cron.

Мы разберем два основных подхода: логические дампы через pg_dump/mysqldump и файловые копии через volumes. Каждый метод имеет свои преимущества для разных сценариев. В статье приведены конкретные команды Docker, примеры скриптов и инструкции по восстановлению данных после сбоя.

Зачем резервное копирование в Docker - это не только про volumes

Docker volumes обеспечивают сохранность данных между перезапусками контейнеров, но не защищают от повреждения файлов, ошибок приложения или сбоя хоста. Volume привязан к конкретному хосту Docker. Если хост выходит из строя, данные в volume становятся недоступными.

Для построения отказоустойчивой системы нужна стратегия резервного копирования, которая включает:

  • Логические дампы через pg_dump (PostgreSQL) и mysqldump (MySQL) - создают переносимые SQL-файлы
  • Файловые копии volumes - сохраняют полное состояние кластера БД
  • Автоматизацию через cron - обеспечивает регулярное создание бэкапов
  • Хранение вне хоста - защищает от физического сбоя сервера

Эта статья охватывает оба подхода с готовыми командами для каждого сценария.

Готовые команды для быстрого резервного копирования

Эти команды можно скопировать и запустить немедленно. Они работают с контейнерами PostgreSQL и MySQL, запущенными через Docker.

Резервная копия PostgreSQL с помощью pg_dump

Для создания дампа работающего контейнера PostgreSQL используйте команду docker exec:

docker exec -t postgres_container pg_dump -U postgres -d database_name -F c -b -v -f /tmp/backup.dump

Ключевые флаги pg_dump:

  • -F c - формат custom, поддерживает сжатие и параллельное восстановление
  • -b - включает большие объекты (BLOBs)
  • -v - подробный вывод для отладки
  • --clean - добавляет команды DROP перед CREATE (для чистого восстановления)
  • --if-exists - использует IF EXISTS с DROP для избежания ошибок
  • --no-owner - не устанавливает владельца объектов при восстановлении

Для безопасной передачи пароля используйте переменную окружения PGPASSWORD:

docker exec -e PGPASSWORD=your_password -t postgres_container pg_dump -U postgres -d database_name -F c -f /tmp/backup.dump

Альтернативный вариант - запуск временного контейнера с доступом к сети основного:

docker run --rm --network container:postgres_container -e PGPASSWORD=your_password postgres:15 pg_dump -h localhost -U postgres -d database_name -F c > backup.dump

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

docker cp postgres_container:/tmp/backup.dump ./backup_$(date +%Y%m%d_%H%M%S).dump

Резервная копия MySQL/MariaDB с помощью mysqldump

Для контейнера MySQL команда создания дампа через docker exec:

docker exec mysql_container mysqldump -u root -psecret --single-transaction --routines --events --databases database_name > /tmp/backup.sql

Важные флаги mysqldump:

  • --single-transaction - создает консистентный снимок для InnoDB таблиц
  • --routines - включает хранимые процедуры и функции
  • --events - включает события планировщика
  • --databases - указывает базы данных для резервирования
  • --all-databases - резервирует все базы данных

Передача пароля через переменную MYSQL_PWD (с оговоркой о безопасности):

docker exec -e MYSQL_PWD=secret mysql_container mysqldump -u root --single-transaction database_name > /tmp/backup.sql

Более безопасный подход - использование конфигурационного файла:

docker exec mysql_container mysqldump --defaults-file=/etc/mysql/backup.cnf --single-transaction database_name > /tmp/backup.sql

Для копирования дампа на хост:

docker cp mysql_container:/tmp/backup.sql ./mysql_backup_$(date +%Y%m%d_%H%M%S).sql

Создание резервной копии через копирование файлов данных (Volumes)

Этот метод подходит для создания полных снепшотов кластера БД, включая системные каталоги. Он работает быстрее для больших баз данных, но требует остановки БД или работает только для неактивных данных.

Использование docker cp для копирования директории данных:

docker cp postgres_container:/var/lib/postgresql/data ./postgres_data_backup

Важно: этот метод копирует файлы, которые могут быть в неконсистентном состоянии, если БД активна. Для консистентной копии нужно остановить контейнер перед выполнением команды.

Архивация Docker Volume с помощью утилиты tar

Создание переносимого архива всего volume через временный контейнер:

docker run --rm -v postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres_volume_$(date +%Y%m%d).tar.gz -C /data .

Пояснение команды:

  • --rm - удаляет контейнер после завершения
  • -v postgres_data:/data - монтирует volume postgres_data в /data контейнера
  • -v $(pwd):/backup - монтирует текущую директорию хоста в /backup
  • alpine - минимальный образ Linux с утилитой tar
  • tar czf - создает сжатый архив в формате gzip
  • -C /data . - указывает исходную директорию для архивации

Эта команда сохраняет права доступа файлов и создает готовый архив для хранения или переноса.

Восстановление данных из резервной копии: пошаговые сценарии

Восстановление данных - критическая операция при сбоях. Эти инструкции покрывают основные сценарии восстановления.

Восстановление из дампа PostgreSQL

Для восстановления из plain-дампа (SQL-файла):

docker exec -i postgres_container psql -U postgres -d database_name < backup.sql

Для восстановления из custom-формата с использованием pg_restore:

docker exec -i postgres_container pg_restore -U postgres -d database_name -v /tmp/backup.dump

Создание новой базы данных перед восстановлением:

docker exec postgres_container psql -U postgres -c "CREATE DATABASE new_database;"
docker exec -i postgres_container pg_restore -U postgres -d new_database -v /tmp/backup.dump

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

docker run --name test_restore -e POSTGRES_PASSWORD=secret -d postgres:15
docker cp backup.dump test_restore:/tmp/
docker exec test_restore pg_restore -U postgres -d postgres -v /tmp/backup.dump

Восстановление из дампа MySQL

Восстановление SQL-дампа в существующую базу данных:

docker exec -i mysql_container mysql -u root -psecret database_name < backup.sql

Создание базы данных и восстановление:

docker exec mysql_container mysql -u root -psecret -e "CREATE DATABASE restored_db;"
docker exec -i mysql_container mysql -u root -psecret restored_db < backup.sql

Для восстановления процедур и триггеров убедитесь, что дамп создан с флагами --routines и --events.

Восстановление из копии файлов Volume

Восстановление архива volume в новый или существующий volume:

  1. Остановите контейнер, использующий volume: docker stop postgres_container
  2. Создайте временный контейнер для распаковки: docker run --rm -v postgres_data:/data -v $(pwd):/backup alpine sh -c "rm -rf /data/* && tar xzf /backup/postgres_volume.tar.gz -C /data"
  3. Запустите контейнер с восстановленным volume: docker start postgres_container

Важно: команда rm -rf /data/* удаляет все существующие данные в volume. Убедитесь, что архив корректен перед выполнением.

Для безопасного восстановления в новый volume:

docker volume create postgres_data_restored
docker run --rm -v postgres_data_restored:/data -v $(pwd):/backup alpine tar xzf /backup/postgres_volume.tar.gz -C /data
docker run --name postgres_restored -v postgres_data_restored:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret -d postgres:15

Автоматизация резервного копирования: скрипты и cron

Ручное создание бэкапов ненадежно. Автоматизация через cron обеспечивает регулярное резервное копирование без вмешательства администратора.

Пример скрипта для автоматического бэкапа PostgreSQL

#!/bin/bash

# Конфигурация
CONTAINER_NAME="postgres_container"
DB_NAME="production_db"
BACKUP_DIR="/var/backups/postgres"
RETENTION_DAYS=30

# Создание директории для бэкапов
mkdir -p "$BACKUP_DIR"

# Имя файла с timestamp
BACKUP_FILE="$BACKUP_DIR/pg_backup_$(date +%Y%m%d_%H%M%S).dump"

# Создание дампа
docker exec -e PGPASSWORD="$DB_PASSWORD" "$CONTAINER_NAME" \
  pg_dump -U postgres -d "$DB_NAME" -F c -b -v -f "/tmp/current_backup.dump"

# Проверка успешности выполнения
if [ $? -eq 0 ]; then
  # Копирование дампа на хост
  docker cp "$CONTAINER_NAME:/tmp/current_backup.dump" "$BACKUP_FILE"
  
  # Очистка временного файла в контейнере
  docker exec "$CONTAINER_NAME" rm -f "/tmp/current_backup.dump"
  
  # Удаление старых бэкапов
  find "$BACKUP_DIR" -name "pg_backup_*.dump" -mtime +$RETENTION_DAYS -delete
  
  echo "$(date): Backup successful: $BACKUP_FILE" >> "$BACKUP_DIR/backup.log"
else
  echo "$(date): Backup failed" >> "$BACKUP_DIR/backup.log"
  exit 1
fi

Скрипт включает проверку кода возврата, ротацию бэкапов и логирование. Для MySQL адаптируйте команды дампа соответствующим образом.

Настройка планировщика задач Cron

Добавьте задание в crontab для ежедневного запуска в 2:00:

0 2 * * * /usr/bin/docker exec postgres_container pg_dump -U postgres -d production_db -F c -f /tmp/backup.dump && /usr/bin/docker cp postgres_container:/tmp/backup.dump /var/backups/postgres/pg_backup_$(date +\%Y\%m\%d).dump

Или используйте bash-скрипт с перенаправлением вывода в лог-файл:

0 2 * * * /opt/scripts/backup_postgres.sh >> /var/log/postgres_backup.log 2>&1

Ключевые моменты настройки cron:

  • Указывайте полный путь к docker и docker-compose
  • Экранируйте символы процента в команде date
  • Перенаправляйте stdout и stderr в лог-файл для диагностики
  • Устанавливайте правильные переменные окружения в скрипте

Для комплексной автоматизации резервного копирования Docker volumes изучите наше полное руководство по настройке отказоустойчивого бэкапа Docker Volumes с поддержкой инкрементального копирования в S3.

Лучшие практики для production-среды

Базовых команд недостаточно для production. Эти практики помогут построить надежную систему резервного копирования.

Сравнение методов: когда что использовать

pg_dump/mysqldump (логические дампы):

  • Плюсы: переносимость между версиями СУБД, сжатие данных, выборочное восстановление таблиц, проверка целостности
  • Минусы: медленнее для больших БД, требует ресурсов CPU, может не захватить все объекты
  • Применение: регулярные бэкапы, миграция между версиями, разработка и тестирование

Копирование volumes (физические копии):

  • Плюсы: быстрее для больших БД, полный снепшот состояния, включает системные каталоги
  • Минусы: привязка к версии СУБД, требует остановки БД или специальных инструментов, больший размер
  • Применение: полные резервные копии, аварийное восстановление, клонирование окружений

Для оптимизации производительности томов с базами данных используйте рекомендации из статьи оптимизация производительности Docker-томов, которые могут увеличить скорость операций ввода-вывода на 10-30%.

Чек-лист перед внедрением в production

  1. Протестировали восстановление на тестовом стенде? Проверка должна включать восстановление в чистый контейнер с проверкой целостности данных.
  2. Бэкапы хранятся на отдельном физическом носителе? Используйте стратегию 3-2-1: три копии, два типа носителей, одна копия вне площадки.
  3. Настроены уведомления об ошибках cron? Мониторинг успешности выполнения заданий через логи, email или системы мониторинга.
  4. Документирован процесс восстановления для коллег? Инструкция должна быть доступна даже при недоступности основной инфраструктуры.
  5. Регулярно проверяете целостность бэкапов? Периодическое восстановление в тестовое окружение выявляет проблемы до аварии.
  6. Настроена ротация бэкапов? Автоматическое удаление старых копий экономит место и упрощает управление.

Для production-развертывания Docker с мониторингом и логированием изучите полное руководство по безопасному деплою Docker в production с health checks и blue-green деплоем.

Резервное копирование - не дополнительная опция, а обязательный компонент инфраструктуры. Начните с простых cron-заданий, постепенно внедряя мониторинг, проверку целостности и хранение вне хоста. Регулярное тестирование восстановления - единственный способ гарантировать работоспособность бэкапов при реальном сбое.

Поделиться:
Сохранить гайд? В закладки браузера