База данных MySQL — это сердце большинства веб-приложений, хранящее бесценную информацию: от пользовательских аккаунтов до финансовых транзакций. Потеря этих данных может стать катастрофой для бизнеса. Автоматизация резервного копирования через собственный скрипт — это не роскошь, а обязательная практика для любого администратора, которая гарантирует спокойный сон и быструю возможность восстановления в случае сбоя.
Почему именно скрипт, а не ручное копирование?
Ручное создание дампов — это человеческий фактор, забывчивость и ошибки. Скрипт работает по расписанию, четко и без эмоций. Он обеспечивает консистентность (согласованность) данных на момент создания бэкапа, что критически важно для транзакционных систем. Автоматизация — это основа любой стратегии Disaster Recovery.
Создаем базовый, но мощный скрипт на Bash
Самый распространенный и гибкий способ — написать скрипт для командной оболочки Bash. Он может работать на любом Linux-сервере.
Ключевые компоненты скрипта
- Утилита mysqldump: «Рабочая лошадка» для создания логических дампов. Она преобразует структуру и данные в набор SQL-команд.
- Параметры командной строки: Определяют, что копировать (одну БД, все, определенные таблицы), и как (с блокировками или без).
- Логирование: Запись результатов работы скрипта в лог-файл для последующего аудита.
- Обработка ошибок: Проверка кодов возврата команд, чтобы скрипт не молчал о проблемах.
- Ротация архивов: Автоматическое удаление старых бэкапов для экономии места.
Важно! Для создания дампа скрипту нужны учетные данные с достаточными привилегиями (минимум SELECT, LOCK TABLES, SHOW VIEW, TRIGGER). Никогда не храните пароль в скрипте в чистом виде! Используйте конфигурационный файл с ограниченными правами доступа (chmod 600).
Пример практического скрипта
Рассмотрим готовый пример с комментариями:
#!/bin/bash
# ============================================
# Скрипт резервного копирования MySQL
# ============================================
# Конфигурация
BACKUP_DIR="/var/backups/mysql"
MYSQL_USER="backup_user"
MYSQL_PASSWORD_FILE="/root/.my.backup.cnf" # Файл с паролем
DATABASE_NAME="my_app_db"
DAYS_TO_KEEP=7
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
LOG_FILE="$BACKUP_DIR/backup.log"
# Создание директории, если её нет
mkdir -p $BACKUP_DIR
# Имя файла бэкапа
BACKUP_FILE="$BACKUP_DIR/${DATABASE_NAME}_${TIMESTAMP}.sql.gz"
# Логирование начала
echo "[$(date)] Начало резервного копирования БД: $DATABASE_NAME" >> $LOG_FILE
# Создание дампа с использованием файла конфигурации для пароля
# Ключевые параметры:
# --single-transaction — для InnoDB, обеспечивает консистентность без блокировок.
# --routines — сохраняет хранимые процедуры и функции.
# --events — сохраняет события планировщика.
# --triggers — сохраняет триггеры (включено по умолчанию в новых версиях).
mysqldump --defaults-extra-file=$MYSQL_PASSWORD_FILE \
--user=$MYSQL_USER \
--single-transaction \
--routines \
--events \
$DATABASE_NAME | gzip > $BACKUP_FILE
# Проверка успешности выполнения mysqldump
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "[$(date)] ОШИБКА: Не удалось создать дамп БД $DATABASE_NAME" >> $LOG_FILE
exit 1
fi
# Проверка, что архив создан и не пустой
if [ -s $BACKUP_FILE ]; then
FILE_SIZE=$(du -h $BACKUP_FILE | cut -f1)
echo "[$(date)] УСПЕХ: Бэкап создан: $BACKUP_FILE (размер: $FILE_SIZE)" >> $LOG_FILE
else
echo "[$(date)] ОШИБКА: Файл бэкапа пуст или не создан!" >> $LOG_FILE
exit 1
fi
# Очистка старых бэкапов (ротация)
find $BACKUP_DIR -name "${DATABASE_NAME}_*.sql.gz" -mtime +$DAYS_TO_KEEP -delete 2>/dev/null
echo "[$(date)] Резервное копирование завершено." >> $LOG_FILE
Планирование выполнения с помощью Cron
Скрипт бесполезен, если его не запускать автоматически. Для этого используется планировщик Cron.
# Открываем crontab для редактирования crontab -e # Добавляем строку для ежедневного запуска в 2:00 ночи 0 2 * * * /bin/bash /путь/к/вашему/скрипту/backup_mysql.sh
Совет продвинутого уровня: Для очень больших баз рассмотрите использование физического копирования файлов данных (например, через Percona XtraBackup) или репликации на «горячий» standby-сервер. Это минимизирует время простоя при восстановлении.
Стратегия 3-2-1 — золотой стандарт
Создания файла на диске недостаточно. Придерживайтесь правила:
- 3 копии данных.
- На 2 разных типах носителей (например, локальный SSD + облачное хранилище).
- 1 копия должна быть географически удаленной (другой дата-центр или S3/Selectel/Yandex Cloud).
aws s3 cp или rclone.
Тестирование восстановления — самая важная часть
Бэкап, который никогда не тестировался на восстановление, — это не бэкап, а надежда. Регулярно (хотя бы раз в квартал) выполняйте процедуру восстановления дампа на тестовый сервер и проверяйте целостность данных. Включите это в свой регламент.
FAQ: Часто задаваемые вопросы
Какой параметр mysqldump использовать для минимальной блокировки таблиц?
Для движка InnoDB используйте --single-transaction. Он создает снимок данных на момент начала дампа внутри транзакции, не блокируя таблицы для записи надолго. Для MyISAM этот параметр не работает, может потребоваться --lock-tables.
Мой дамп получается огромным. Как его оптимизировать?
Используйте сжатие на лету (как в примере: | gzip). Также можно исключать большие, не критичные таблицы с помощью опции --ignore-table=database.table. Для инкрементального бэкапа рассмотрите инструменты вроде Percona XtraBackup.
Как автоматически удалять старые бэкапы?
В примере скрипта используется команда find с параметром -mtime +$DAYS_TO_KEEP. Она удаляет файлы старше указанного количества дней. Это классическая ротация.
Безопасно ли хранить пароль в скрипте?
Нет, категорически нет! Всегда используйте опцию --defaults-extra-file, которая читает учетные данные из защищенного файла с правами доступа 600. Никогда не передавайте пароль через аргументы командной строки, так как он может быть виден другим пользователям в списке процессов (ps aux).
Как сделать бэкап всех баз данных на сервере?
Используйте параметр --all-databases вместо указания имени конкретной БД. Не забудьте выделить больше места для хранения и убедитесь, что у пользователя есть глобальные привилегии.