mysqldump导出必须加--single-transaction和--routines:前者保证InnoDB一致性快照,后者导出存储过程、函数、触发器;推荐命令含--triggers、--events、--hex-blob及utf8mb4字符集显式指定。

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 而不是直接拷表。










