mysqldump导出需加--single-transaction(innodb)、--routines --triggers --events、--set-gtid-purged=off(非gtid环境)、--default-character-set=utf8mb4,才能保障数据一致性、完整性与兼容性。

能快速迁移,但“快”不等于“无风险”——关键看数据量、停机容忍度和版本兼容性。小于10GB且允许停机5分钟,mysqldump + mysql 是最稳的选择;超过100GB或要求秒级切换,必须绕开逻辑导出,走物理复制或主从同步。
用 mysqldump 导出时加哪些参数才真正一致?
很多人导出后发现主键丢失、时间戳错乱、触发器没生效,问题往往出在参数缺失。默认不带任何选项的 mysqldump 只导结构+数据,不保事务一致性、不导存储过程、不处理字符集隐式转换。
-
--single-transaction:对 InnoDB 表加一致性快照,避免导出过程中写入导致数据不一致;MyISAM 表必须配合--lock-all-tables,否则可能丢数据 -
--routines --triggers --events:显式带上这三个,否则存储过程、触发器、定时事件全丢 -
--set-gtid-purged=OFF:迁移到非 GTID 环境(如老版本 MySQL 或云托管实例)时必须关掉,否则导入报错ERROR 1840 (HY000) -
--default-character-set=utf8mb4:强制指定字符集,防止源库character_set_client设置异常导致导出乱码
导入前目标库必须检查的三项配置
导入失败十次里有七次是因为目标库“看起来能连,实际不能用”。别跳过这三步:
- 执行
SHOW VARIABLES LIKE 'sql_mode';,确保目标库没启用严格模式(如STRICT_TRANS_TABLES),否则含空字符串或零日期的字段会直接报错中断 - 确认
max_allowed_packet值 ≥ 导出文件最大单行长度(可先用head -n 100 backup.sql | wc -L估算),否则导入中途卡死无提示 - 检查
innodb_log_file_size是否与源库一致——若不一致且导入前未清理旧日志,MySQL 启动会拒绝加载,报错InnoDB: Error: log file ./ib_logfile0 is of different size
大表导入慢?不是磁盘 IO 问题,而是 autocommit 默认开着
导入 1GB 以上 SQL 文件时,如果每条 INSERT 都单独提交,性能会暴跌 5–10 倍。这不是配置问题,是客户端行为。
- 导入命令开头加
SET autocommit=0;,结尾加COMMIT;,或者用mysql --init-command="SET autocommit=0" -u user -p db_name - 禁用唯一键校验:
SET unique_checks=0;和SET foreign_key_checks=0;放在导入前,能提速 30%–60%,导入完再设回=1 - 别用
source命令在 MySQL CLI 里导入大文件——它单行解析、无缓冲,容易内存溢出;直接走 shell 管道:mysql -u user -p db_name
跨版本迁移最容易被忽略的兼容性断点
MySQL 5.7 → 8.0 看似平滑,但几个默认行为变化会让导入静默失败:
- 8.0 默认启用
caching_sha2_password插件,如果目标用户没显式指定认证插件,旧应用连接会报Authentication plugin 'caching_sha2_password' cannot be loaded - 保留关键字新增:如
rank、json在 8.0 成为关键字,若你的表名/列名撞上,导入时需用反引号包裹,否则语法错误 - 系统表结构变更:
mysql.user表字段增减(如account_locked),直接拷贝整个--all-databases备份到 8.0 会失败,必须排除系统库单独导业务库
真正耗时的从来不是传输或导入本身,而是字符集隐式转换、权限继承错位、以及那些没报错但数据逻辑已损坏的 silent corruption。做一次 CHECKSUM TABLE 对比,比反复重跑迁移更省时间。











