迁移失败最常被忽略的原因是源库和目标库MySQL版本不匹配;需检查VERSION()、遵循官方升级路径,导出时用--routines --triggers --single-transaction --set-gtid-purged=OFF,导入前对齐字符集与权限,并校验CHECKSUM及建表语句。

确认源库和目标库的 MySQL 版本兼容性
版本不匹配是迁移失败最常被忽略的原因。5.7 → 8.0 可能因 mysql.user 表结构变更、默认认证插件(caching_sha2_password)导致权限导入失败;而 8.0 → 5.7 则可能因 JSON 字段、不可见索引等新特性报错。
迁移前务必执行:SELECT VERSION(); 分别查源库和目标库版本,再查阅 MySQL 官方升级路径文档,确认是否支持直接逻辑导出导入。跨大版本(如 5.6 → 8.0)建议先升级源库到中间版本,或改用物理拷贝(仅限同构且停机允许)。
用 mysqldump 导出时必须加的关键参数
默认 mysqldump 不包含建库语句、忽略存储过程、可能锁表——这些都会让导入中断或数据不全。
推荐导出命令(以数据库 myapp 为例):
mysqldump -u root -p --routines --triggers --single-transaction --set-gtid-purged=OFF myapp > myapp.sql
-
--routines:导出存储过程和函数(否则mysqldump默认跳过) -
--triggers:导出触发器 -
--single-transaction:对 InnoDB 表做一致性快照,避免锁表(MyISAM 表仍会锁) -
--set-gtid-purged=OFF:禁用 GTID 相关语句,防止在非 GTID 环境下报错
若源库有大量 BLOB 或长文本,建议额外加 --max-allowed-packet=512M 避免导出中途截断。
导入时权限与字符集要提前对齐
导入失败常见于目标库缺失用户、字符集不一致或 SQL 模式限制严格。
导入前在目标库执行:
CREATE DATABASE IF NOT EXISTS myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
并确保目标用户有 CREATE、INSERT、ALTER 权限。如果导入报错 ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER',说明 MySQL 8.0 已移除该模式,需在导入前执行:
SET sql_mode = (SELECT REPLACE(@@sql_mode,'NO_AUTO_CREATE_USER',''));
或临时修改目标库配置文件 my.cnf 中的 sql_mode 值,去掉已废弃项。
验证数据完整性不能只看行数
行数一致 ≠ 数据一致。BLOB 截断、时间戳时区偏移、浮点精度丢失、外键约束未启用等情况都可能导致静默差异。
基础校验步骤:
- 检查导入日志末尾是否有
Query OK和Records: X Duplicates: Y Warnings: Z,Warnings非零需排查 - 对比关键表的
CHECKSUM TABLE mytable;(源库和目标库分别执行,结果应完全相同) - 抽样查几条含时间、JSON、emoji 的记录,确认字段内容未被截断或转义
- 运行
SHOW CREATE TABLE对比源库和目标库的建表语句,确认索引、约束、字符集完全一致
真正麻烦的是跨平台迁移(如 Linux → Windows),文件路径大小写、行尾符、甚至 lower_case_table_names 设置不同,都可能让后续应用查询失败——这点容易被跳过,但上线后很难回溯。










