Потеря базы данных — катастрофа для бизнеса. Автоматические ежедневные бэкапы — это страховка, которую настраивают один раз и забывают.
Простой скрипт резервного копирования
#!/bin/bash
# /usr/local/bin/mysql-backup.sh
DB_USER="root"
DB_PASS="ВашПароль"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y-%m-%d_%H-%M)
KEEP_DAYS=7
mkdir -p "$BACKUP_DIR"
# Получить список всех баз данных
DATABASES=$(mysql -u"$DB_USER" -p"$DB_PASS" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|sys)")
for DB in $DATABASES; do
echo "Backup: $DB"
mysqldump -u"$DB_USER" -p"$DB_PASS" --single-transaction --routines --triggers "$DB" | gzip > "$BACKUP_DIR/${DB}_${DATE}.sql.gz"
done
# Удалить старые бэкапы
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +"$KEEP_DAYS" -delete
echo "Backup complete: $(ls -lh $BACKUP_DIR | tail -5)"
chmod +x /usr/local/bin/mysql-backup.sh
# Добавить в cron (каждый день в 2:00)
echo "0 2 * * * root /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1" >> /etc/crontab
Восстановление из бэкапа
# Распаковать и восстановить
gunzip < /var/backups/mysql/mydb_2026-01-25_02-00.sql.gz | mysql -u root -p mydb
Хранение бэкапов в облаке (S3/Backblaze)
# Установить AWS CLI
sudo apt install -y awscli
# Настроить
aws configure
# Загрузить в S3
aws s3 sync /var/backups/mysql/ s3://your-bucket/mysql-backups/ --storage-class STANDARD_IA
Разбор типичных ошибок бэкапа
mysqldump завершается с "Error: 'Access denied; you need (at least one of) the PROCESS privilege(s)'" — возникает при использовании --single-transaction с пользователем без права PROCESS, нужного для чтения списка процессов при снятии консистентного снепшота.
mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
Выдайте нужные права: GRANT PROCESS, RELOAD, LOCK TABLES ON *.* TO 'backup_user'@'localhost'; — отдельный пользователь только для бэкапов безопаснее, чем root в скрипте.
Файл бэкапа весит 0 байт или обрывается на середине — типичный признак того, что закончилось место на диске в момент выполнения дампа, а скрипт не проверяет код возврата mysqldump.
df -h /var/backups
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 20G 0 100% /
mysqldump: Got errno 28 on write
errno 28 — это ENOSPC, "No space left on device". Добавьте в скрипт проверку свободного места перед стартом и проверку кода выхода после mysqldump, чтобы не хранить битые архивы как будто это успешный бэкап.
Стратегии резервного копирования: сравнение
| Метод | Блокирует таблицы | Подходит для больших БД | Инструмент |
|---|---|---|---|
| mysqldump --single-transaction | Нет (только InnoDB) | До ~50 ГБ комфортно | mysqldump (входит в клиент MySQL) |
| mysqldump без --single-transaction | Да, FLUSH TABLES WITH READ LOCK | Небольшие БД или тестовые окружения | mysqldump |
| Физический бэкап (hot copy) | Нет | Сотни ГБ и больше | Percona XtraBackup |
| Снепшот диска/VPS | Нет | Любой размер, но без гарантии консистентности БД | Снепшоты хостинга (LVM, ZFS) |
Когда mysqldump не подходит
- База данных больше 50–100 ГБ — mysqldump создаёт текстовый SQL-дамп, восстановление которого может занимать часы; для таких объёмов используйте физический бэкап через XtraBackup.
- Нужен бэкап без остановки записи и без нагрузки на I/O в рабочее время — снятие полного дампа большой базы создаёт заметную нагрузку, планируйте его на ночное окно.
- Требуется point-in-time восстановление (откат на конкретную секунду) — для этого нужны бинарные логи и отдельная стратегия, а не просто периодический дамп.
Проверка результата
- Проверьте, что архив не пустой и не битый:
gzip -t /var/backups/mysql/mydb_*.sql.gz— команда должна завершиться без ошибок. - Разверните дамп в тестовую базу и сверьте количество таблиц:
mysql -e "SHOW TABLES" testdb | wc -lдолжно совпадать с исходной базой. - Проверьте, что cron действительно выполняет задачу:
grep mysql-backup /var/log/syslogдолжен показывать записи за каждый день. - Убедитесь, что копия бэкапа реально попадает в облако:
aws s3 ls s3://your-bucket/mysql-backups/ | tail -5должен показывать свежие файлы.
Для самой настройки MariaDB перед бэкапом см. статью об установке и настройке MariaDB, а для восстановления больших дампов — руководство по импорту больших дампов.
Частые вопросы
Нужно ли останавливать сервер MySQL перед запуском mysqldump?
Нет, останавливать сервер не требуется — именно для этого существует флаг single-transaction, который снимает консистентный снимок данных InnoDB-таблиц без блокировки записи. Приложение продолжает работать во время дампа, читая и записывая данные как обычно, а резервная копия получается целостной благодаря транзакционному механизму, а не остановке сервиса.
Можно ли восстановить бэкап в базу данных с другим именем, чем у оригинала?
Да, дамп mysqldump — это обычный SQL-текст с командами создания и наполнения таблиц, поэтому его можно подать в базу данных с любым именем, если заранее создать эту базу и ссылаться на неё при восстановлении. Имя базы в самом дампе не жёстко привязано к оригинальному названию, если дамп не создавался с флагом полной базы целиком.
Достаточно ли хранить бэкап локально на том же сервере, где работает база данных?
Нет, хранить резервную копию исключительно на том же сервере опасно: если сервер взломан, вышел из строя или диск повреждён, локальная копия пропадает вместе с оригиналом. Правильная стратегия предполагает выгрузку копии за пределы сервера — в облачное хранилище или на другую машину, иначе смысл резервного копирования теряется.
Нужно ли дополнительно бэкапить файлы сайта, или бэкапа одной базы данных достаточно?
Резервная копия только базы данных покрывает структуру и содержимое таблиц, но не файлы сайта — загруженные медиа, конфигурацию приложения или собственный код, который обычно не хранится в базе. Полноценная стратегия восстановления подразумевает отдельное резервное копирование файловой системы наряду с дампом базы данных.