迁移前须检查engine和charset兼容性,确认版本差异导致的myisam转innodb、新校对规则不支持等问题;mysqldump需添加--no-create-db、--skip-extended-insert、--set-gtid-purged=off等参数;外键与索引须按序重建;timestamp/datetime默认值及时区行为需显式处理;sql_mode差异易致插入失败。

迁移前必须检查 ENGINE 和 CHARSET
不同 MySQL 版本或目标库对存储引擎和字符集支持有差异。比如从 MySQL 5.6 迁移到 8.0,MyISAM 表可能被强制转为 InnoDB;而 utf8mb4_0900_as_cs 这类 8.0 新 collation 在旧版本根本不存在,会导致 CREATE TABLE 报错 Unknown collation。
- 用
SHOW CREATE TABLE `t_name`确认源表的ENGINE和DEFAULT CHARSET、COLLATE - 目标库执行
SELECT VERSION(), @@default_storage_engine, @@collation_server核对兼容性 - 若需降级迁移(如 8.0 → 5.7),务必手动替换
json字段为text、删掉INVISIBLE列、去掉DESC在索引定义中的非法用法
mysqldump 导出时别漏掉关键参数
默认 mysqldump 不包含 CREATE DATABASE、不处理 GTID、不保留外键约束顺序,直接导入容易失败或数据不一致。
- 加
--no-create-db避免在已有库中重复建库报错 - 加
--skip-extended-insert方便定位插入失败的具体行(但会增大 SQL 文件体积) - 加
--set-gtid-purged=OFF(若目标库不启 GTID 或是新实例) - 加
--skip-triggers如果触发器逻辑依赖源环境(比如调用 UDF 或写外部文件)
外键和索引重建顺序不能乱
导出的 SQL 默认按“先建表、再建索引、最后加外键”顺序,但若目标库已存在部分表,或迁移中途失败重试,ALTER TABLE ... ADD FOREIGN KEY 可能因引用表尚未创建/无对应索引而报错 ERROR 1215 (HY000): Cannot add foreign key constraint。
- 人工拆分 SQL:先确保所有表结构建完,再统一执行
CREATE INDEX(尤其被引用列必须有索引) - 外键语句单独提取,放在最后批量执行;或用
SET FOREIGN_KEY_CHECKS=0包裹,但导入后务必验证一致性 - 注意
ON DELETE CASCADE类行为在目标库是否开启(innodb_foreign_key_checks是运行时变量,不影响建表)
时间类型字段在 5.6/5.7/8.0 间迁移最易踩坑
TIMESTAMP 的自动初始化、时区行为、默认值限制在各版本变化极大。MySQL 5.6 允许 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,但 5.7 起要求第一个 TIMESTAMP 才能带 CURRENT_TIMESTAMP 默认值;8.0 更进一步,DATETIME 也支持 CURRENT_TIMESTAMP,但语义和时区处理与 TIMESTAMP 不同。
- 导出前用
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_DEFAULT, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t' AND DATA_TYPE IN ('timestamp','datetime')检查默认值写法 - 避免依赖隐式默认(如
TIMESTAMP无默认值时自动设为CURRENT_TIMESTAMP),显式写出DEFAULT CURRENT_TIMESTAMP - 跨时区迁移时,确认
time_zone系统变量和连接时区设置,否则TIMESTAMP值可能偏移
sql_mode 差异——源库宽松(如允许空字符串插入 NOT NULL 字段),目标库严格(STRICT_TRANS_TABLES 开启),导致 INSERT 直接失败。建议迁移前在目标库执行 SELECT @@sql_mode 并比对。










