Как установить и настроить Percona XtraBackup на VPS
Классический mysqldump на боевой базе — это боль: если база больше пары гигабайт, дамп идёт минутами, а восстановление из него — часами, потому что mysqldump пишет SQL-инструкции, которые надо заново проиграть и переиндексировать. Percona XtraBackup решает это иначе: копирует файлы данных InnoDB напрямую, применяет журнал транзакций и получает согласованный снимок без блокировки таблиц на чтение и запись. Разберём установку, полные и инкрементальные бэкапы, восстановление и типичные грабли на VPS.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое XtraBackup и когда он нужен
XtraBackup — бесплатный инструмент от Percona для горячего резервного копирования MySQL, MariaDB, Percona Server. В отличие от логического бэкапа (mysqldump), он делает физическую копию: читает файлы .ibd, ib_logfile*, применяет redo-log, чтобы снимок был консистентным на момент завершения копирования, а не старта.
Когда он оправдан:
- база от нескольких гигабайт — восстановление из физического бэкапа кратно быстрее, чем проигрывание SQL-дампа;
- нужен бэкап без простоя и без длинных блокировок на проде под нагрузкой;
- нужны инкрементальные бэкапы — снимать не всю базу каждый раз, а только изменения;
- планируете point-in-time recovery — восстановление на конкретный момент с применением бинарных логов поверх бэкапа.
Когда логического дампа хватает: маленькая база (до 1-2 ГБ), редкие изменения, нужен просто SQL-файл для миграции между версиями. XtraBackup не отменяет mysqldump, а дополняет его там, где важна скорость восстановления.
Нюанс: InnoDB бэкапится без блокировок, но таблицы MyISAM (если остались) копируются с кратковременной блокировкой на запись в конце процесса. На чистом InnoDB блокировок не будет вообще.
Установка и права доступа
Percona держит свой репозиторий с готовыми пакетами. Версию нужно подбирать под сервер: для MySQL 8.0 подходит percona-xtrabackup-80 — сверьтесь с матрицей совместимости на сайте Percona, версии выпускаются отдельно под ветки MySQL 5.7/8.0/8.4.
# Ставим репозиторий Percona
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
sudo apt update
# Включаем нужный компонент — для XtraBackup 8.0
sudo percona-release setup pxb-80
sudo apt install -y percona-xtrabackup-80
# Проверяем версию
xtrabackup --version
Для MariaDB актуальнее использовать mariabackup — форк XtraBackup, который MariaDB Foundation тестирует именно на MariaDB InnoDB/Aria и синтаксис которого почти идентичен xtrabackup (дальше в статье примеры даны для xtrabackup, для MariaDB замените команду на mariabackup):
sudo apt install -y mariadb-backup
mariabackup --version
На CentOS/AlmaLinux/RockyLinux ставится через percona-release и yum:
sudo yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
sudo percona-release setup pxb-80
sudo yum install -y percona-xtrabackup-80
Права доступа и подготовка
XtraBackup нужен прямой доступ к файлам данных MySQL (/var/lib/mysql) и MySQL-пользователь с правами на бэкап. Создайте отдельного пользователя, не используйте root:
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'СложныйПароль123!';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT, BACKUP_ADMIN ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
BACKUP_ADMIN появился в MySQL 8.0 и нужен именно для XtraBackup — без него бэкап упадёт с ошибкой доступа. Для MariaDB достаточно RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT.
Пароль лучше не держать в командной строке (попадёт в history и в вывод ps aux), а вынести в конфиг:
sudo mkdir -p /etc/xtrabackup
sudo tee /etc/xtrabackup/backup.cnf > /dev/null <<'EOF'
[client]
user=backup_user
password=СложныйПароль123!
EOF
sudo chmod 600 /etc/xtrabackup/backup.cnf
Дальше вызываем бэкап с --defaults-extra-file=/etc/xtrabackup/backup.cnf — пароль не светится в процессах. Если запускаете бэкап не от root, а от отдельного сервисного пользователя, добавьте его в группу mysql для доступа на чтение к каталогу данных.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПолный и инкрементальный бэкап
Создаём каталог назначения и снимаем полный бэкап:
sudo mkdir -p /var/backups/mysql/full
sudo xtrabackup --backup \
--defaults-extra-file=/etc/xtrabackup/backup.cnf \
--target-dir=/var/backups/mysql/full/$(date +%F_%H-%M-%S) \
--datadir=/var/lib/mysql
XtraBackup копирует файлы InnoDB, параллельно читает redo-log и дописывает изменения, произошедшие уже в процессе копирования. В конце пишет xtrabackup_checkpoints и xtrabackup_info — метаданные о снимке с LSN (log sequence number).
Такой бэкап ещё не готов к восстановлению — он содержит незавершённые транзакции. Нужен этап prepare:
sudo xtrabackup --prepare --target-dir=/var/backups/mysql/full/2026-08-28_03-00-00
Prepare "докатывает" redo-log поверх файлов и откатывает незакоммиченные транзакции — на выходе получаете консистентный снимок, готовый к копированию в datadir. Именно на этом этапе чаще всего вылетает ошибка нехватки памяти на большой базе — см. раздел про грабли ниже.
Для сжатия на лету добавьте --compress (нужен qpress, ставится отдельно, apt install qpress), для параллелизма — --parallel=4 (число потоков, ориентируйтесь на число ядер VPS минус 1-2, чтобы не забрать всё CPU у самого MySQL).
Инкрементальные бэкапы
Полный бэкап каждую ночь на базе от 50-100 ГБ — это и время, и место на диске. Инкрементальные бэкапы копируют по LSN только страницы, изменившиеся с прошлого снимка.
Первый инкремент — от полного бэкапа:
sudo xtrabackup --backup \
--defaults-extra-file=/etc/xtrabackup/backup.cnf \
--target-dir=/var/backups/mysql/inc/2026-08-29_03-00-00 \
--incremental-basedir=/var/backups/mysql/full/2026-08-28_03-00-00
Следующий инкремент — от предыдущего инкремента, не от полного:
sudo xtrabackup --backup \
--defaults-extra-file=/etc/xtrabackup/backup.cnf \
--target-dir=/var/backups/mysql/inc/2026-08-30_03-00-00 \
--incremental-basedir=/var/backups/mysql/inc/2026-08-29_03-00-00
Восстановление цепочки сложнее, чем полного бэкапа — нужно применить prepare последовательно к каждому звену, начиная с базового (разберём в следующем разделе). Типичная схема: полный бэкап раз в неделю, инкременты каждую ночь — баланс между временем восстановления и местом на диске.
Восстановление из бэкапа
Восстановление — самая ответственная часть, и её стоит хотя бы раз потренировать на копии сервера заранее.
1. Останавливаем MySQL и освобождаем datadir:
sudo systemctl stop mysql
sudo mv /var/lib/mysql /var/lib/mysql_old_$(date +%F)
sudo mkdir /var/lib/mysql
sudo chown mysql:mysql /var/lib/mysql
2. Готовим бэкап (prepare), если ещё не готовили:
Для полного бэкапа — как в разделе выше. Для цепочки полный + инкременты — применяем prepare последовательно, с флагом --apply-log-only на всех звеньях, кроме последнего:
# Шаг 1: применяем к полному бэкапу изменения без финального отката транзакций
sudo xtrabackup --prepare --apply-log-only \
--target-dir=/var/backups/mysql/full/2026-08-28_03-00-00
# Шаг 2: накатываем первый инкремент поверх полного
sudo xtrabackup --prepare --apply-log-only \
--target-dir=/var/backups/mysql/full/2026-08-28_03-00-00 \
--incremental-dir=/var/backups/mysql/inc/2026-08-29_03-00-00
# Шаг 3: последний инкремент — уже без --apply-log-only, это финальный prepare
sudo xtrabackup --prepare \
--target-dir=/var/backups/mysql/full/2026-08-28_03-00-00 \
--incremental-dir=/var/backups/mysql/inc/2026-08-30_03-00-00
Флаг --apply-log-only важен: без него на промежуточных шагах XtraBackup откатит незакоммиченные транзакции раньше времени, и следующий инкремент накатить будет нельзя.
3. Копируем готовый бэкап в datadir:
sudo xtrabackup --copy-back --target-dir=/var/backups/mysql/full/2026-08-28_03-00-00
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql
--copy-back копирует файлы; вместо него можно использовать --move-back, если места на диске впритык — но тогда исходный каталог бэкапа будет уничтожен, так что держите копию в другом месте.
После старта проверьте логи (journalctl -u mysql -n 100) и статус реплики, если она была настроена — координаты бинарного лога сохраняются в xtrabackup_binlog_info внутри каталога бэкапа, их нужно использовать при пересоздании репликации на реплике-получателе.
Автоматизация: cron и ротация
Бэкап без автоматизации — это бэкап, который рано или поздно забудут снять. Скрипт для cron:
#!/bin/bash
# /usr/local/bin/xtrabackup-full.sh
set -euo pipefail
BACKUP_DIR="/var/backups/mysql/full/$(date +%F_%H-%M-%S)"
CNF="/etc/xtrabackup/backup.cnf"
LOG="/var/log/xtrabackup.log"
mkdir -p "$BACKUP_DIR"
xtrabackup --backup \
--defaults-extra-file="$CNF" \
--target-dir="$BACKUP_DIR" \
--datadir=/var/lib/mysql \
--compress --parallel=2 \
>> "$LOG" 2>&1
xtrabackup --prepare --target-dir="$BACKUP_DIR" >> "$LOG" 2>&1
# Удаляем бэкапы старше 14 дней
find /var/backups/mysql/full -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
echo "$(date): backup completed at $BACKUP_DIR" >> "$LOG"
sudo chmod +x /usr/local/bin/xtrabackup-full.sh
sudo crontab -e
Добавьте строку:
0 3 * * 0 /usr/local/bin/xtrabackup-full.sh
0 3 * * 1-6 /usr/local/bin/xtrabackup-inc.sh
Полный — по воскресеньям, инкременты — в остальные дни (скрипт инкремента строится по аналогии, только с --incremental-basedir). Подробнее про отладку cron-задач — в статье про cron-задачи на VPS.
Обязательно настройте копирование готовых бэкапов на другой сервер или в объектное хранилище (rsync, rclone) — бэкап, который лежит на том же диске, что и база, не спасёт при отказе диска или компрометации сервера целиком.
Частые проблемы и как их избежать
Копирование файлов InnoDB на лету — процесс с нюансами, и часть ошибок повторяется у всех, кто настраивает XtraBackup впервые.
Prepare падает с ошибкой нехватки памяти. По умолчанию --prepare использует буфер около 100 МБ, чего может не хватить на большой базе с активным redo-log. Увеличьте буфер: --use-memory=1G. На VPS с 2-4 ГБ RAM не ставьте больше половины доступной памяти — иначе может упасть сам MySQL, если он работает параллельно.
Ошибка "Access denied" на PROCESS или BACKUP_ADMIN. Пользователю не выдали нужную привилегию (см. раздел про права выше) — MySQL 8.0 без BACKUP_ADMIN не даст снять консистентный снимок LSN.
Бэкап занимает диска больше, чем ожидалось. Без --compress физический бэкап занимает примерно столько же места, сколько сам datadir. Планируйте место с запасом минимум в 1.5-2 раза от текущего размера базы. Если места впритык, проверьте заодно, не растут ли логи бесконтрольно — это отдельная тема, разобранная в статье про нехватку места под данные MySQL.
Инкремент не применяется — "log sequence number mismatch". Вы применили инкремент не в том порядке или указали не тот --incremental-basedir/--incremental-dir. LSN должен идти строго по возрастанию — сверяйте xtrabackup_checkpoints в каждом каталоге перед восстановлением.
Бэкап "успешно завершился", но при restore MySQL не стартует. Почти всегда причина — забыли финальный --prepare без --apply-log-only на последнем звене цепочки, или скопировали файлы без chown mysql:mysql. Проверьте права на /var/lib/mysql после --copy-back в первую очередь.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем XtraBackup лучше mysqldump?
Делает физический бэкап без блокировки InnoDB-таблиц и восстанавливается кратно быстрее на больших базах — копированием файлов, а не проигрыванием SQL. mysqldump проще, но восстановление из дампа на базе от нескольких гигабайт может занять часы.
Можно ли использовать XtraBackup с MariaDB?
Да, но предпочтительнее mariabackup — форк с той же логикой, который MariaDB Foundation тестирует на своих версиях сервера. Синтаксис почти идентичен.
Нужно ли останавливать MySQL для бэкапа?
Нет — снимок делается на работающем сервере без блокировки чтения и записи (кроме кратковременной блокировки в конце для MyISAM-таблиц, если они есть).
Сколько места нужно под бэкапы?
Ориентируйтесь минимум на полный размер базы плюс 30-50% на инкременты и временные файлы. Точная цифра зависит от частоты изменений — тестируйте на своих данных.
Как проверить, что бэкап рабочий, не дожидаясь аварии?
Периодически разворачивайте его на отдельном тестовом VPS и проверяйте, что MySQL стартует, а данные читаются. Бэкап, который ни разу не восстанавливали, — это не бэкап, а надежда.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →