mysql从旧服务器迁移到新服务器_mysql全量迁移步骤

来源:这里教程网 时间:2026-02-28 20:45:27 作者:

mysqldump 导出时必须加
--single-transaction
--routines

不加

--single-transaction
,在有写入的旧库上导出可能产生不一致快照,尤其对 InnoDB 表;而
--routines
是为了导出存储过程、函数、触发器——这些默认不被包含。如果业务依赖自定义函数或定时触发逻辑,漏掉会导致新库功能异常。

推荐导出命令:

mysqldump -h old_host -u user -p --single-transaction --routines --triggers --events --hex-blob --default-character-set=utf8mb4 database_name > dump.sql
--triggers
--events
显式加上,避免因 MySQL 版本差异导致默认行为变化
--hex-blob
防止二进制字段(如
VARBINARY
BLOB
)在导出时被错误转义
务必确认旧库字符集是
utf8mb4
,否则导出文件里中文可能乱码,导入后变成问号或截断

导入前要在新服务器上创建同名数据库并指定
utf8mb4
字符集

直接

CREATE DATABASE db_name;
会继承 MySQL 实例默认字符集,而很多老服务器默认还是
latin1
utf8
(即 utf8mb3)。一旦库级字符集不对,即使
dump.sql
里声明了
CHARSET=utf8mb4
,表和列仍可能建错。

安全做法是显式指定:

CREATE DATABASE `database_name` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
导入前执行
SET NAMES utf8mb4;
,确保客户端连接使用正确编码
如果导入报错
ERROR 1366 (HY000): Incorrect string value
,大概率是某张表的列没继承库级字符集,需检查
dump.sql
CREATE TABLE
语句是否含
CHARSET=utf8mb4
不要依赖
my.cnf
的全局设置来“一劳永逸”,迁移过程必须显式控制

导入大文件时禁用唯一性检查和自动提交能提速 5–10 倍

默认导入会逐条插入并校验唯一索引、外键,还频繁刷盘。对于百万级以上数据,这会让导入从几分钟拖到几小时。

dump.sql
开头手动插入三行(或用 sed 预处理):

SET FOREIGN_KEY_CHECKS=0;
SET UNIQUE_CHECKS=0;
SET AUTOCOMMIT=0;

并在结尾补上:

SET UNIQUE_CHECKS=1;
SET FOREIGN_KEY_CHECKS=1;
COMMIT;
跳过唯一性检查只在确认源数据本身无重复的前提下才安全 关闭
AUTOCOMMIT
后,整个导入变成一个事务,内存压力增大,但 IO 减少显著;若中途失败,需重跑全量
导入完成后务必手动执行
SHOW ENGINE INNODB STATUS\G
查看是否有未释放的锁或长事务残留

迁移后必须验证
mysql.proc
表和
DEFINER
权限问题

存储过程/函数导出时会带

DEFINER=`user`@`host`
,如果新库没有这个用户,或者用户权限不足,调用时会报
ERROR 1449 (HY000): The user specified as a definer does not exist

导入后运行
SELECT db, name, type, definer FROM mysql.proc WHERE db = 'database_name';
检查所有对象的
definer
批量修正:用
mysqldump
--skip-definer
重新导出,或导入后执行
UPDATE mysql.proc SET definer='new_user@localhost' WHERE db='database_name';
(注意操作前先
FLUSH TABLES
别忘了
GRANT EXECUTE ON PROCEDURE
给应用账号,否则即使过程存在也无法调用

跨版本迁移(比如 5.7 → 8.0)时,

mysql.proc
表结构已废弃,改用
information_schema.routines
,此时必须用
mysqldump --routines
而不是直接拷表。

相关推荐