Перенос MySQL на новый сервер состоит из трёх частей: базы данных, пользователи с правами и настройки сервера. Базы переносятся дампом, пользователей лучше пересоздать скриптом, а настройки - перенести вручную, сверив с новой версией. Всё ниже относится и к MariaDB, отличия отмечены.
Инструкция подходит для MySQL 8.0 и 8.4 LTS и MariaDB 10.6-11.x.
Подготовка
-
Сравните версии на старом и новом сервере:
mysql --versionилиSELECT VERSION();. Перенос дампом работает между разными версиями и даже из MySQL в MariaDB и обратно, но при большой разнице версий проверьте заметки об обновлении: меняются значения по умолчанию, типы аутентификации, зарезервированные слова. -
Посмотрите, что переносить:
SELECT table_schema AS db, ROUND(SUM(data_length + index_length) / 1024 / 1024) AS size_mb FROM information_schema.tables GROUP BY table_schema;Системные базы
mysql,information_schema,performance_schemaиsysцеликом не переносите - на новом сервере они свои. -
Проверьте место на новом сервере: нужно место под дамп и под сами базы.
-
Решите, как быть с записью. Если в базы постоянно пишут, на время финального переноса остановите приложение или переведите его в режим только для чтения, иначе изменения, сделанные после начала дампа, потеряются.
Перенос баз через mysqldump

В MariaDB 11 утилиты называются mariadb-dump и mariadb. Старые имена mysqldump и mysql пока работают, но выводят предупреждение, поэтому в скриптах для MariaDB лучше сразу писать новые.
Дамп
mysqldump -u root -p --single-transaction --routines --triggers --events \
--databases shop blog > dump.sql
--single-transaction- согласованный снимок без блокировки таблиц InnoDB. Для таблиц MyISAM он не помогает - их блокируют на время дампа или предварительно останавливают запись.--routines,--triggers,--events- хранимые процедуры, функции, триггеры и события. Без--routinesи--eventsони в дамп не попадут.--databases- в дамп добавятся командыCREATE DATABASEиUSE, базы создадутся с прежними именами.
Чтобы выгрузить все пользовательские базы, получите их список:
mysql -u root -p -N -e "SHOW DATABASES" | grep -Ev '^(mysql|information_schema|performance_schema|sys)$'
и передайте его в --databases.
Дамп хорошо сжимается:
mysqldump ... --databases shop blog | gzip > dump.sql.gz
Передача и загрузка
scp dump.sql.gz user@new-server:/tmp/
ssh user@new-server
gunzip < /tmp/dump.sql.gz | mysql -u root -p
Без промежуточного файла
Если места мало или базы большие, дамп можно сразу загрузить на новый сервер через SSH:
mysqldump -u root -p --single-transaction --routines --triggers --events --databases shop \
| gzip | ssh user@new-server "gunzip | mysql -u root -p'пароль'"
Пароль в командной строке виден в списке процессов. Лучше на обоих серверах положить учётные данные в файл ~/.my.cnf с правами 600:
[client]
user=root
password=пароль
и не указывать -u и -p вовсе.
Кодировка
Если базы в utf8mb4, ничего делать не нужно: mysqldump по умолчанию использует эту кодировку. Если в старых базах кодировка cp1251 или latin1, перед переносом проверьте, что после загрузки текст читается правильно, - на тестовой копии, не на боевом сервере.
Перенос пользователей и прав

Копировать таблицу mysql.user между разными версиями нельзя: структура системных таблиц меняется. Правильно - выгрузить команды создания пользователей и выдачи прав.
На старом сервере список пользователей:
SELECT user, host FROM mysql.user
WHERE user NOT IN ('root', 'mysql.sys', 'mysql.session', 'mysql.infoschema', 'debian-sys-maint', 'mariadb.sys');
Для каждого пользователя получите команды:
SHOW CREATE USER 'shop'@'localhost';
SHOW GRANTS FOR 'shop'@'localhost';
SHOW CREATE USER выводит пользователя вместе с хешем пароля, так что пароли знать не нужно. Скрипт, который соберёт всё в один файл:
mysql -N -e "SELECT CONCAT('''', user, '''@''', host, '''') FROM mysql.user
WHERE user NOT IN ('root','mysql.sys','mysql.session','mysql.infoschema','debian-sys-maint','mariadb.sys')" |
while read u; do
mysql -N -e "SHOW CREATE USER $u" | sed 's/$/;/'
mysql -N -e "SHOW GRANTS FOR $u" | sed 's/$/;/'
done > users.sql
Перенесите users.sql на новый сервер, просмотрите его и выполните:
mysql < users.sql
Особенности:
- Плагин аутентификации. В MySQL 8 по умолчанию используется
caching_sha2_password, в старых версиях и MariaDB -mysql_native_password. В MySQL 8.4 плагинmysql_native_passwordпо умолчанию отключён (включается параметромmysql_native_password=ONв конфигурации), а в MySQL 9 удалён совсем, поэтому пользователей со старым плагином при переходе на 8.4 нужно перевести наcaching_sha2_password. Хеш одного плагина не подходит для другого. Если при выполнении скрипта возникает ошибка или пользователь не может войти, задайте пароль заново:ALTER USER 'shop'@'localhost' IDENTIFIED BY 'пароль';. - Перенос в MariaDB из MySQL 8 и обратно - формат
SHOW CREATE USERразличается, проще создать пользователей вручную с новыми паролями и выдать права по выводуSHOW GRANTS. - Хост. Если приложение будет подключаться к базе с другого сервера, адрес в
'user'@'host'должен соответствовать его адресу или подсети.
Для больших инсталляций MySQL удобна утилита MySQL Shell: util.dumpInstance() и util.loadDump() переносят базы вместе с пользователями и работают заметно быстрее mysqldump, потому что выгружают и загружают данные в несколько потоков.
Перенос настроек
Конфигурация лежит в /etc/mysql/ (Debian, Ubuntu) или /etc/my.cnf и /etc/my.cnf.d/ (RHEL и родственные). Не копируйте файл целиком - сравните параметры и перенесите только свои изменения: размер буферов (innodb_buffer_pool_size), max_connections, bind-address, режим SQL (sql_mode), кодировки. Некоторые параметры из старых версий в новых удалены, и сервер с ними не запустится.
Прямое копирование файлов
Для одинаковых версий MySQL на одинаковой платформе можно скопировать папку данных целиком - это быстрее дампа для больших баз:
- Остановите MySQL на обоих серверах.
- Скопируйте папку данных (обычно
/var/lib/mysql):rsync -aH /var/lib/mysql/ new-server:/var/lib/mysql/. - Проверьте владельца файлов (
mysql:mysql) и, в системах с SELinux, контексты (restorecon -R /var/lib/mysql). - Запустите MySQL на новом сервере.
Пользователи при этом переносятся вместе с базой mysql. Между разными версиями этот способ не используйте.
Проверка и переключение
- Сравните число таблиц и строк в важных таблицах на старом и новом сервере (
SELECT COUNT(*) FROM ...). - Проверьте, что процедуры и триггеры на месте:
SHOW PROCEDURE STATUS WHERE Db = 'shop';,SHOW TRIGGERS FROM shop;. - Войдите на новый сервер от имени каждого пользователя приложения.
- Если приложения будут подключаться по сети, проверьте
bind-addressв настройках сервера и откройте порт 3306 в файрволе только для нужных адресов. - Переключите приложения на новый сервер (адрес в конфигурации или запись DNS), убедитесь, что всё работает, и только потом выключайте старый.





Не столкнувшись с проблемой переноса баз данных вплотную — даже не мог себе представить, что в MySQL, фактически, — НАЧИСТО отсутствует штатный механизм переноса привилегий пользователей!
P.S. До этого, считал MySQL довольно-таки приличной СУБД, которая подходит для большинства задач, а теперь — хочется плеваться.
Ну, привилегии переносятся не каждый день…
Так что можно и потерпеть 🙂
*** Getting info about blabla…
и висим
разобрался, скопипастил в файл неудачно)
а вот ошибка уже при импорте на удаленном вылезла
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘GRANT ALL PRIVILEGES ON `user\\_number2`.* TO ‘user_number2’@’%’
Три года прошло с момента публикации статьи, а как пригодилась сегодня. Столкнулся с такой же бедой как и у тебя, понятно что для тебя это уже неактуально, но может быть кто-то еще найдет эту статью и попадет на те же грабли 🙂
Вот подправленный вариант, мб кому и пригодится 🙂
http://thelinuxforce.org/upload/files/MysqlMigrate_v2.rar
Можно копировать папку /var/lib/mysql целиком, предварительно остановив mysql на обоих серверах. Если баз огромная куча, будет быстрее.