Перенос базы данных MySQL на другой сервер без простоя
📖 Гайды

Как перенести базу данных MySQL на другой сервер без простоя

Марина
Марина
📅 27 мая 2026 👁 133 просмотров
Как перенести базу данных MySQL на другой сервер без простоя

Перенести базу данных MySQL на другой сервер без простоя — задача с несколькими правильными решениями. Какое из них подходит, зависит от объёма базы и допустимого downtime: для базы в 2 ГБ хватит mysqldump за 10 минут, для продакшн-проекта на 100 ГБ нужна репликация master–slave или Percona XtraBackup. В этом руководстве — все три метода с реальными командами, разбором ошибок и чеклистом на финале.

Почему «просто скопировать файлы» не работает

Распространённая ошибка при переезде на новый сервер — скопировать директорию /var/lib/mysql/ через rsync или scp, пока MySQL запущен. Результат — повреждённая база или silent data corruption, который обнаружится не сразу, а через несколько дней в виде битых записей. Для тех, кто переезжает с виртуального хостинга, есть отдельное руководство: как перенести сайт на VPS пошагово.

Что будет с InnoDB при «горячем» копировании

InnoDB держит в памяти буфер пула (InnoDB buffer pool), redo log и незафиксированные транзакции. Файлы .ibd на диске в любой момент могут быть в промежуточном состоянии — страницы записаны частично, WAL-лог не применён. Когда вы копируете такие файлы и запускаете MySQL на новом сервере, движок начинает recovery и обнаруживает несоответствие — база либо не стартует, либо стартует с потерей данных.

Когда допустима остановка сервиса

Если база используется для разработки или на тестовом стенде — остановить MySQL, скопировать /var/lib/mysql/, запустить на новом сервере. Быстро и без риска при условии совпадения версий MySQL.

Для продакшн-проекта с SLA остановка неприемлема. Здесь нужен один из методов ниже: mysqldump с --single-transaction, репликация или XtraBackup.

Метод 1. mysqldump — надёжно для баз до 10 ГБ

mysqldump создаёт логический дамп: SQL-файл с командами CREATE TABLE и INSERT, который воспроизводит структуру и данные на любом сервере. Плюсы — кросс-версионность и простота. Минус — при импорте больших баз MySQL построчно выполняет INSERT’ы, что на 50 ГБ займёт несколько часов. Полная официальная документация mysqldump — на сайте MySQL.

Дамп с минимальной блокировкой (—single-transaction)

mysqldump -u root -p \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --hex-blob \
  имя_базы > /tmp/backup.sql

Что делает каждый ключ:

  • —single-transaction — открывает транзакцию с изоляцией REPEATABLE READ, снимает консистентный снимок без блокировки таблиц. Работает только для InnoDB. Для MyISAM нужен --lock-tables.
  • —routines — включает хранимые процедуры и функции
  • —triggers — включает триггеры (без этого ключа они не попадут в дамп)
  • —events — включает запланированные события
  • —hex-blob — BLOB-поля в hex-формате, защита от проблем с кодировкой

Передача дампа на новый сервер

Вариант 1 — scp для небольших файлов:

scp /tmp/backup.sql user@new-server:/tmp/

Вариант 2 — пайп через SSH без промежуточного файла. Экономит дисковое место и ускоряет перенос больших дампов:

mysqldump -u root -p --single-transaction \
  --routines --triggers имя_базы \
  | gzip | ssh user@new-server "gunzip | mysql -u root -p имя_базы"

На новом сервере база должна быть создана заранее: CREATE DATABASE имя_базы CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Восстановление и проверка целостности

# Импорт дампа
mysql -u root -p имя_базы < /tmp/backup.sql

# Проверка всех таблиц
mysqlcheck -u root -p --all-databases

# Контрольные проверки после импорта
mysql -u root -p -e "SHOW TABLE STATUS FROM имя_базы;"
mysql -u root -p -e "SELECT COUNT(*) FROM имя_базы.важная_таблица;"

Метод 2. Репликация master–slave — миграция без остановки для больших баз

Как перенести базу данных MySQL на другой сервер без простоя — иллюстрация

Для баз объёмом более 10 ГБ или проектов с требованием к минимальному downtime — репликация. Схема: новый сервер становится slave и догоняет master в реальном времени. Когда Seconds_Behind_Master = 0, переключаем приложение. Суммарный downtime — 30–120 секунд.

Подготовка master: binary log и пользователь репликации

# /etc/mysql/mysql.conf.d/mysqld.cnf (или my.cnf) — добавить в [mysqld]
[mysqld]
server-id   = 1
log_bin     = /var/log/mysql/mysql-bin.log
binlog_do_db = имя_базы
expire_logs_days = 7

После изменения конфига — systemctl restart mysql. Затем создаём пользователя репликации:

CREATE USER 'repl'@'IP_SLAVE' IDENTIFIED BY 'сложный_пароль';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'IP_SLAVE';
FLUSH PRIVILEGES;

Снятие консистентного дампа с позицией binlog

mysqldump -u root -p \
  --single-transaction \
  --master-data=2 \
  --routines --triggers \
  имя_базы > /tmp/master_dump.sql

Флаг --master-data=2 добавляет в начало дампа закомментированную строку CHANGE MASTER TO с координатами binlog — файлом и позицией в момент снятия дампа. Это ключевой момент: slave будет реплицировать с этой точки, не пропуская и не дублируя транзакции.

Настройка slave и запуск репликации

На новом сервере — отдельный server-id в конфиге, затем импортируем дамп и настраиваем репликацию:

# Импорт дампа на slave
mysql -u root -p имя_базы < /tmp/master_dump.sql

# Настройка репликации (координаты берём из начала master_dump.sql)
CHANGE MASTER TO
  MASTER_HOST='IP_MASTER',
  MASTER_USER='repl',
  MASTER_PASSWORD='сложный_пароль',
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=12345;

START SLAVE;
SHOW SLAVE STATUS\G

В выводе SHOW SLAVE STATUS смотрим три поля: Slave_IO_Running: Yes, Slave_SQL_Running: Yes и Seconds_Behind_Master. Последнее должно уменьшаться — slave догоняет master. Когда достигнет 0 — можно переключать.

Переключение приложения — момент X

Когда Seconds_Behind_Master = 0:

  1. Включить режим обслуживания в приложении (или переключить DNS на время)
  2. Выполнить на новом сервере: STOP SLAVE;
  3. Сменить строку подключения к БД в конфиге приложения на IP нового сервера
  4. Выключить режим обслуживания, проверить работу

Оставьте старый сервер в режиме standby ещё сутки — на случай если понадобится откат.

Метод 3. Percona XtraBackup — горячий физический бэкап для InnoDB

XtraBackup делает физическую копию файлов InnoDB без остановки MySQL и без блокировки таблиц. Главное преимущество перед mysqldump: восстановление базы 100 ГБ занимает 15–20 минут против 2–4 часов при импорте SQL-дампа — потому что файлы просто копируются, а не воспроизводятся INSERT'ами. Подробности — в документации Percona XtraBackup.

Установка и создание бэкапа

# Установка на Debian/Ubuntu
apt install percona-xtrabackup-80

# Создание бэкапа
xtrabackup --backup \
  --user=root \
  --password=пароль \
  --target-dir=/tmp/xtrabackup/

# Подготовка (применяет redo log, делает файлы консистентными)
xtrabackup --prepare --target-dir=/tmp/xtrabackup/

Этап --prepare обязателен: без него файлы бэкапа несогласованны — часть транзакций не применена. После prepare директория содержит консистентный снимок базы, готовый к копированию.

Восстановление на новом сервере

# Остановить MySQL на новом сервере
systemctl stop mysql

# Скопировать бэкап (директория /var/lib/mysql должна быть пустой или чистой)
rsync -avz --progress /tmp/xtrabackup/ user@new-server:/var/lib/mysql/

# На новом сервере: выставить права
ssh user@new-server "chown -R mysql:mysql /var/lib/mysql"

# Запустить MySQL
ssh user@new-server "systemctl start mysql"

XtraBackup работает только при совпадении мажорной версии MySQL — бэкап с 8.0 не восстановится на 5.7. Для кросс-версионной миграции — только mysqldump.

Сравнение методов — что выбрать

Как перенести базу данных MySQL на другой сервер без простоя — иллюстрация

Метод Размер базы Downtime Сложность Кросс-версионность
mysqldump До 10 ГБ Минуты–часы Низкая Да
Репликация master–slave Любой 30–120 сек Средняя Да (осторожно)
Percona XtraBackup Более 10 ГБ InnoDB Секунды Средняя Нет (та же версия)

Частые ошибки при переносе MySQL

Разные версии MySQL — несовместимый формат

Дамп из MySQL 8.0 не всегда корректно импортируется в 5.7: в 8.0 появились зарезервированные слова (RANK, GROUPS, SYSTEM), которые в 5.7 воспринимаются как имена столбцов. Редакция рекомендует переносить на ту же или более новую версию. Если нужна кросс-версионная миграция — проверяйте дамп на тестовом стенде.

Кодировка: utf8 vs utf8mb4

Если на старом сервере база создана с utf8 (в MySQL это псевдоним для utf8mb3, не поддерживает emoji и некоторые китайские символы), а на новом — utf8mb4, данные импортируются, но COLLATION таблиц и столбцов может не совпасть. Проверить:

SHOW CREATE TABLE имя_таблицы\G

Если CHARSET=utf8 — при импорте на новый сервер принудительно указать нужную кодировку или сконвертировать таблицы после переноса через ALTER TABLE.

Забытые хранимые процедуры и триггеры

Вызов mysqldump без --routines --triggers не включает процедуры, функции и триггеры в дамп. Приложение после переноса работает, но теряет бизнес-логику, зашитую в БД. Проверить перед дампом:

SHOW PROCEDURE STATUS WHERE Db = 'имя_базы';
SHOW TRIGGERS FROM имя_базы;

Права доступа пользователей не переносятся автоматически

Таблица mysql.user не дампится при стандартном вызове с указанием конкретной базы. Права приложения на новом сервере нужно воссоздать вручную или дополнительно дампить системную базу:

# Экспорт прав всех пользователей (MySQL 8.0+)
mysqldump -u root -p mysql user db tables_priv > /tmp/users_grants.sql

# Или на старом сервере собрать GRANT-запросы вручную
SHOW GRANTS FOR 'пользователь'@'%';

Переключение DNS и проверка после переноса

После переключения приложения на новый сервер — стандартный набор проверок:

  • Тестовые запросы к базе: операции чтения и записи
  • Логи ошибок MySQL: tail -f /var/log/mysql/error.log
  • Активные процессы: SHOW PROCESSLIST; — нет ли висящих запросов
  • Если оставили репликацию активной — мониторинг Seconds_Behind_Master на случай отката
  • Мониторинг производительности: SHOW STATUS LIKE 'Innodb_buffer_pool%';

После переноса базы следующий шаг — настройка окружения на сервере с нуля: читайте руководство как настроить VPS с нуля.

VPS для MySQL: что важно в характеристиках

RAM для MySQL важнее CPU: InnoDB buffer pool должен вмещать рабочий набор данных. Стандартная рекомендация — 50–70% оперативной памяти под buffer pool. При базе 20 ГБ нужно минимум 8–16 ГБ RAM.

По дискам: NVMe vs SATA SSD — разница принципиальная для write-heavy нагрузки. NVMe даёт 3–5 Гбайт/с последовательной записи против 500–600 Мбайт/с у SATA SSD. Для высоконагруженных баз с частыми UPDATE/INSERT — только NVMe. Подробный разбор: NVMe vs SSD для сервера.

Провайдеры с NVMe-дисками и подходящими конфигурациями для MySQL: Aeza и Selectel. Сравнить по гео, RAM и типу диска можно по фильтрам каталога VPS в России. Если нужны конкретные конфигурации — сравнить конфигурации в каталоге.

Ну и в заключение: чеклист переноса MySQL — 10 шагов

  1. Снять тестовый дамп заранее — убедиться, что mysqldump проходит без ошибок, на старом сервере ещё до начала переноса
  2. Зафиксировать версию MySQL на старом сервере: mysql --version
  3. Проверить наличие процедур и триггеров: SHOW PROCEDURE STATUS, SHOW TRIGGERS
  4. Выбрать метод по объёму базы и допустимому downtime (см. таблицу выше)
  5. Создать базу на новом сервере с нужной кодировкой (utf8mb4)
  6. Перенести данные выбранным методом
  7. Воссоздать права пользователей — не забыть про application user
  8. Проверить целостность: mysqlcheck --all-databases, контрольные COUNT(*)
  9. Включить режим обслуживания, переключить строку подключения в конфиге приложения
  10. Выключить режим обслуживания, проверить логи MySQL и логи приложения в течение 15–30 минут

Если старый сервер тормозит MySQL из-за нехватки RAM или SATA-дисков — в каталоге VPS-хостингов можно подобрать конфигурацию с NVMe и от 4 ГБ RAM под задачи баз данных. Там же — фильтр по локации и провайдеру.

Поделиться:
Марина
Редактор · FREEHOSTING
Главный редактор FREEHOSTING. С 2020 года тестирует VDS, VPS и хостинг-провайдеров — арендует серверы, нагружает их реальными проектами и пишет честные обзоры по итогам. Помогает читателям выбирать хостинг под свои задачи: от Telegram-бота до production-сайта.