MAATRIX / Блог / Percona XtraBackup на сервере: частые ошибки и решения

Percona XtraBackup на сервере: частые ошибки и решения

MAATRIX

mysqldump на базе в 50-100 ГБ идёт часами и держит блокировки, от которых приложение начинает тормозить или вовсе виснет на записи. Percona XtraBackup решает эту проблему — он копирует файлы InnoDB напрямую, без остановки сервиса, но за эту скорость приходится платить своей порцией специфических ошибок: несовпадение версий, битые бэкапы после --prepare, отказ --copy-back из-за занятого datadir. Разберём, откуда растут ноги у самых частых проблем и как их закрывать быстро, без гадания на логах.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Percona XtraBackup и когда он нужен

XtraBackup — это утилита для физического («горячего») бэкапа MySQL и MariaDB. В отличие от mysqldump, который выгружает данные в SQL-команды через логический дамп, XtraBackup копирует непосредственно файлы табличных пространств InnoDB (.ibd, ibdata1) и параллельно читает redo-лог, чтобы зафиксировать все транзакции, которые случились во время копирования. Итог — консистентный снимок базы без FLUSH TABLES WITH READ LOCK на весь процесс (блокировка нужна лишь на доли секунды в конце, для метаданных).

Практическая разница: дамп базы в 80 ГБ через mysqldump может идти часами с ощутимой деградацией на запись, а XtraBackup копирует те же данные со скоростью, ограниченной в основном диском и сетью — обычно кратно быстрее, и без блокировок для читающих/пишущих запросов. Точные цифры зависят от диска, нагрузки и размера буферного пула — не берите это как гарантию, на вашем железе будет иначе.

Для MariaDB форк называется mariabackup — построен на кодовой базе XtraBackup и работает почти идентично, с той же логикой ошибок. Всё, что написано ниже про XtraBackup, применимо и к нему, если явно не сказано иное.

Когда XtraBackup — правильный выбор:

  • База больше 5-10 ГБ и дамп/восстановление через mysqldump занимает неприемлемо долго;
  • Нужен бэкап без блокировок на продакшене под нагрузкой;
  • Нужны инкрементальные бэкапы (полный раз в неделю + дельты каждый день);
  • Планируется быстрое разворачивание реплики или staging-копии базы.

Когда логический дамп всё ещё уместен: маленькие базы, миграция между разными версиями MySQL/MariaDB или между движками (MyISAM ↔ InnoDB), выгрузка отдельных таблиц.

Установка и типичные ошибки на старте

Percona держит собственный репозиторий с пакетами под конкретные версии сервера. Установка на Ubuntu 24.04/22.04:

wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb
sudo dpkg -i percona-release_latest.generic_all.deb
sudo percona-release setup ps80   # или ps57, если у вас MySQL 5.7
sudo apt update
sudo apt install percona-xtrabackup-80

Для MariaDB mariabackup обычно уже входит в пакет mariadb-backup из стандартного репозитория MariaDB и отдельно подключать Percona-репозиторий не нужно:

sudo apt install mariadb-backup

Ошибка 1: несовпадение версии XtraBackup и версии сервера.

xtrabackup: Error: server version does not match backup tool version

XtraBackup жёстко привязан к мажорной версии сервера — percona-xtrabackup-80 понимает MySQL 8.0, но не работает с 5.7 или с MariaDB. Смотрите версию сервера (mysql --version) и ставьте соответствующий пакет: для 5.7 — percona-xtrabackup-24, для 8.0 — percona-xtrabackup-80 (точное имя пакета уточняйте в репозитории на момент установки). Для MariaDB 10.x/11.x — только mariabackup, никогда не XtraBackup.

Ошибка 2: доступ запрещён при первом запуске.

Access denied for user 'backup'@'localhost' (using password: YES)

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

CREATE USER 'xtrabackup'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT, BACKUP_ADMIN ON *.* TO 'xtrabackup'@'localhost';
FLUSH PRIVILEGES;

BACKUP_ADMIN появился в MySQL 8.0 и обязателен — без него --backup падает с ошибкой доступа даже при наличии RELOAD/PROCESS. В MariaDB достаточно RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Ошибки при создании бэкапа (backup stage)

Базовая команда полного бэкапа:

xtrabackup --backup --target-dir=/data/backup/full \
  --user=xtrabackup --password='strong_password_here'

Ошибка: InnoDB: Log scanned before checkpoint или Failed to read redo log header.

Обычно значит, что innodb_log_file_size изменился между запусками, либо XtraBackup не успевает вычитывать redo-лог из-за высокой нагрузки на запись — лог перезаписывается быстрее, чем утилита его читает. Решения:

  • Увеличьте innodb_log_file_size/etc/mysql/mysql.conf.d/mysqld.cnf или /etc/mysql/mariadb.conf.d/50-server.cnf) — это снижает частоту циклической перезаписи лога;
  • На очень нагруженных серверах запускайте бэкап в период минимальной активности (ночью), а не под пиковой записью;
  • Проверьте, что диск, на который пишется бэкап, не является узким местом — если --target-dir медленнее, чем скорость генерации redo-лога, XtraBackup не успевает.

Ошибка: Cannot open datadir / mysqld_safe: Permission denied.

Часто утилита запускается не от того пользователя. XtraBackup должен иметь доступ на чтение к /var/lib/mysql — либо запускайте от root через sudo, либо добавьте пользователя в группу mysql:

sudo usermod -aG mysql backup-runner

Ошибка: место на диске закончилось прямо во время бэкапа.

Физический бэкап по объёму сопоставим с реальным размером данных на диске, а не с логическим размером таблиц — неиспользуемое пространство в ibdata1 тоже копируется. Перед запуском сверяйте свободное место:

du -sh /var/lib/mysql
df -h /data/backup

Если бэкапы регулярно упираются в диск, обычно проще заранее взять сервер с запасом под хранение хотя бы 2-3 полных копий плюс инкременты, чем чистить диск в аварийном режиме на каждом цикле.

Ошибки при подготовке бэкапа (--prepare)

Сырой бэкап после --backup не готов к восстановлению — в нём есть незавершённые транзакции, которые нужно докатить или откатить через redo/undo-лог. Для этого нужен отдельный шаг:

xtrabackup --prepare --target-dir=/data/backup/full

Ошибка: xtrabackup: error: table ... doesn't exist in engine.

Чаще всего это значит, что бэкап уже был подготовлен ранее (--prepare запущен второй раз на том же каталоге) — после первой подготовки внутренняя структура файлов меняется, и повторный --prepare её ломает. Правило простое: --prepare выполняется один раз на каждый каталог с бэкапом. Если нужно попробовать ещё раз — берите свежую копию сырого бэкапа.

Ошибка: нехватка памяти при --prepare на больших базах.

InnoDB: Cannot allocate memory for the buffer pool

По умолчанию --prepare использует 100 МБ буфера, чего может не хватать на базах от десятков гигабайт — процесс либо падает, либо крайне медленно проходит recovery. Увеличьте буфер явно:

xtrabackup --prepare --target-dir=/data/backup/full --use-memory=4G

Значение --use-memory подбирайте по свободной RAM на сервере подготовки (не обязательно на проде — --prepare разумно гонять на отдельной машине или staging-сервере, чтобы не грузить боевой инстанс).

Инкрементальные бэкапы и порядок --prepare.

Для инкрементов важен строгий порядок применения:

# Полный бэкап
xtrabackup --backup --target-dir=/data/backup/full

# Инкремент от полного
xtrabackup --backup --target-dir=/data/backup/inc1 \
  --incremental-basedir=/data/backup/full

# Подготовка: сначала полный без --apply-log-only,
# затем каждый инкремент по порядку
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full \
  --incremental-dir=/data/backup/inc1
xtrabackup --prepare --target-dir=/data/backup/full \
  --incremental-dir=/data/backup/inc1

Частая ошибка новичков — забыть --apply-log-only на промежуточных шагах. Без него redo-лог на первом же шаге считается полностью применённым, и следующие инкременты накатить уже нельзя — восстановление ломается с ошибкой о несовпадении LSN (log sequence number).

Восстановление: --copy-back и типичные проблемы

Финальный шаг — переносим подготовленный бэкап обратно в datadir:

sudo systemctl stop mysql
sudo xtrabackup --copy-back --target-dir=/data/backup/full \
  --datadir=/var/lib/mysql
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql

Ошибка: Original data directory is not empty!.

--copy-back отказывается писать поверх существующих данных — это защита от случайной потери текущей базы. Если это действительно восстановление с нуля, очистите каталог (предварительно убедившись, что старые данные точно не нужны или сохранены отдельно):

sudo mv /var/lib/mysql /var/lib/mysql.old
sudo mkdir /var/lib/mysql

Альтернатива, экономящая место и время на больших базах — --move-back вместо --copy-back: файлы не копируются, а перемещаются. Быстрее, но исходный бэкап уничтожается — используйте, только если есть ещё одна копия на другом хранилище.

Ошибка: сервер не стартует после restore — InnoDB: Unable to lock ./ibdata1.

Почти всегда это забытый chown mysql:mysql — после --copy-back файлы принадлежат тому пользователю, от которого запускался restore (часто root), а mysqld не может открыть их на запись. Права нужно проставить обязательно, это не опциональный шаг.

Если разворачиваете бэкап на новом сервере с другим объёмом RAM, проверьте, что innodb_buffer_pool_size в конфиге целевого сервера не превышает физическую память — иначе mysqld не запустится. Подробнее об этом — в статье про настройку MySQL на VPS.

Автоматизация, инкрементальные бэкапы и мониторинг

Ручной запуск команд быстро надоедает — на практике бэкап оборачивают в скрипт и вешают на cron. Простая схема: полный бэкап раз в неделю, инкременты каждую ночь, ротация старше 14 дней.

#!/bin/bash
set -euo pipefail
BASE=/data/backup
DATE=$(date +%F)
LOG=/var/log/xtrabackup.log

if [ "$(date +%u)" = "1" ]; then
  xtrabackup --backup --target-dir="$BASE/full-$DATE" \
    --user=xtrabackup --password="$XB_PASS" >> "$LOG" 2>&1
else
  LAST=$(ls -td "$BASE"/full-* "$BASE"/inc-* 2>/dev/null | head -1)
  xtrabackup --backup --target-dir="$BASE/inc-$DATE" \
    --incremental-basedir="$LAST" \
    --user=xtrabackup --password="$XB_PASS" >> "$LOG" 2>&1
fi

find "$BASE" -maxdepth 1 -mtime +14 -exec rm -rf {} \;

Важные моменты, которые часто упускают:

  • Проверяйте код выхода. xtrabackup возвращает ненулевой код при ошибке — без set -e бэкап может «завершиться успешно» в глазах cron, реально упав на середине;
  • Мониторьте факт успешного завершения, а не факт запуска. Файл xtrabackup_info появляется только при удачном завершении — его отсутствие через N часов после ожидаемого времени бэкапа — сигнал тревоги;
  • Периодически тестируйте restore. Бэкап, который ни разу не разворачивали на тестовом сервере, с равной вероятностью может быть рабочим или битым;
  • Храните копию не только на сервере-источнике. Если бэкапы лежат на том же диске, что и боевая база, при отказе диска вы теряете и то, и другое сразу — выгружайте их отдельно (rsync, rclone в S3-совместимое хранилище, отдельный сервер под бэкапы).

Про автоматизацию и хранение бэкапов баз данных в целом подробнее написано в статье про резервное копирование баз данных. Если после установки сама СУБД падает или не стартует — отдельно разобраны частые причины в статье про ошибки MySQL на сервере и про MariaDB на сервере.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

XtraBackup работает с MariaDB?

Напрямую — нет, но у MariaDB есть свой форк mariabackup с идентичным синтаксисом команд. Ставьте mariadb-backup из репозитория MariaDB, а не пакет Percona.

Нужно ли останавливать MySQL для бэкапа?

Нет — --backup работает на живом сервере без блокировок для чтения и записи. Остановка нужна только на этапе --copy-back, чтобы не писать поверх работающего datadir.

Чем XtraBackup лучше mysqldump для больших баз?

Физическое копирование быстрее логического дампа в разы на базах от десятков гигабайт, не блокирует таблицы и поддерживает инкрементальные бэкапы — dump всегда полный.

Можно ли восстановить только одну таблицу из полного бэкапа?

Да, через --export на этапе --prepare и ALTER TABLE ... IMPORT TABLESPACE, но с рядом ограничений (например, по внешним ключам) — для точечного восстановления логический дамп конкретной таблицы часто проще.

Сколько места нужно под хранение бэкапов?

Реальный размер данных (du -sh /var/lib/mysql), умноженный на количество хранимых полных копий, плюс инкременты и запас 30-50% сверху.

Как проверить, что бэкап рабочий, не трогая прод?

Разверните --copy-back на отдельном тестовом сервере, запустите MySQL и выполните SELECT по ключевым таблицам — единственный надёжный способ убедиться, что бэкап не битый.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →