Гарячий бекап MySQL з Percona XtraBackup
На відміну від mysqldump, Percona XtraBackup створює резервні копії InnoDB без блокування таблиць і без зупинки сервера. Незамінний для баз даних від 10 ГБ.
Встановлення XtraBackup
# Для Ubuntu/Debian (MySQL 8.0)
wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb
dpkg -i percona-release_latest.generic_all.deb
percona-release setup pdps-80
apt update && apt install percona-xtrabackup-80Повний бекап
# Створення повного бекапу
xtrabackup --backup \
--user=root \
--password='YourPass' \
--target-dir=/backup/full
# Підготовка бекапу до відновлення
xtrabackup --prepare --target-dir=/backup/fullІнкрементальний бекап
# Інкрементальний бекап на основі повного
xtrabackup --backup \
--user=root \
--password='YourPass' \
--target-dir=/backup/inc1 \
--incremental-basedir=/backup/full
# Підготовка: спочатку базовий, потім інкрементальний
xtrabackup --prepare --apply-log-only --target-dir=/backup/full
xtrabackup --prepare --apply-log-only \
--target-dir=/backup/full \
--incremental-dir=/backup/inc1
# Фінальна підготовка
xtrabackup --prepare --target-dir=/backup/fullВідновлення з бекапу
# Зупинити MySQL
systemctl stop mysql
# Очистити datadir
rm -rf /var/lib/mysql/*
# Скопіювати дані
xtrabackup --copy-back --target-dir=/backup/full
# Встановити права
chown -R mysql:mysql /var/lib/mysql
# Запустити MySQL
systemctl start mysqlАвтоматизація через cron
#!/bin/bash
# /etc/cron.d/xtrabackup — щонеділі повний, решту днів інкремент
DATE=$(date +%Y%m%d)
BACKUP_DIR=/backup
if [ $(date +%u) -eq 7 ]; then
# Повний бекап
xtrabackup --backup --user=root --password='Pass' \
--target-dir=$BACKUP_DIR/full_$DATE
else
# Інкрементальний
LAST_FULL=$(ls -td $BACKUP_DIR/full_* | head -1)
xtrabackup --backup --user=root --password='Pass' \
--target-dir=$BACKUP_DIR/inc_$DATE \
--incremental-basedir=$LAST_FULL
fi--compress і шифруйте за допомогою --encrypt=AES256 перед передаванням до віддаленого сховища.Типові помилки XtraBackup
| Помилка | Причина | Рішення |
|---|---|---|
| Failed to connect to MySQL server: Access denied for user | У користувача немає прав RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT | Видати GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup_user'@'localhost'; |
| innodb_log_file_size in backup config differs from server | Під час --prepare сервер порівнює розмір лога бекапу з поточним my.cnf | Не змінювати innodb_log_file_size між бекапом і відновленням, або готувати бекап з явним зазначенням параметра |
| PXB will not copy .frm files for non-InnoDB tables | У базі є таблиці MyISAM, які XtraBackup копіює інакше (не потоково, з короткочасним блокуванням) | Враховувати при розрахунку часу бекапу змішаних баз, див. різницю рушіїв нижче |
Чому XtraBackup не блокує InnoDB, але блокує MyISAM
XtraBackup копіює файли InnoDB напряму з диска, одночасно читаючи redo log, і наприкінці «дописує» зміни, накопичені під час копіювання — таблиці лишаються доступні на запис увесь час бекапу. Для таблиць MyISAM (та інших не-InnoDB рушіїв) такого журналу немає, тому XtraBackup бере FLUSH TABLES WITH READ LOCK на короткий час наприкінці процесу, щоб скопіювати їх консистентно. На базах, де майже всі таблиці — InnoDB, це блокування триває секунди; якщо в базі багато великих таблиць MyISAM, блокування може бути помітне застосунку.
Коли XtraBackup не підходить
Для баз менше кількох гігабайтів різниця в продуктивності зі звичайним mysqldump непринципова, а mysqldump простіше відновлювати частково — на рівні окремих таблиць чи рядків, чого XtraBackup не вміє: він завжди відновлює весь каталог даних цілком. XtraBackup також вимагає, щоб версія сервера і версія утиліти були сумісні (Percona підтримує відповідність major-версіям MySQL/MariaDB) — під час оновлення сервера потрібно перевірити, що встановлений percona-xtrabackup підтримує нову версію, інакше --prepare завершиться помилкою.
Перевірка цілісності бекапу після відновлення
# Переконатися, що сервер піднявся і бачить усі бази
mysql -u root -p -e "SHOW DATABASES;"
# Звірити кількість таблиць з початковим сервером
mysql -u root -p -e "
SELECT table_schema, COUNT(*) AS tables
FROM information_schema.tables
GROUP BY table_schema;"
# Перевірити стан InnoDB після відновлення — не повинно бути recovery-попереджень
SHOW ENGINE INNODB STATUS\G
# Прогнати контрольний запит з очікуваною кількістю рядків
mysql -u root -p mydb -e "SELECT COUNT(*) FROM orders;"Порівняння кількості рядків і таблиць з показниками до бекапу — обов'язковий крок, а не формальність: XtraBackup мовчки завершиться з кодом 0, навіть якщо один із файлів скопіювався не повністю через збій диска, і це з'ясується лише при першому зверненні до пошкодженої таблиці. Логічну альтернативу з порядковим дампом описує стаття про mysqldump і відновлення, а про перенесення змін після повного бекапу — стаття про відновлення на момент часу через binlog.