迁移前必须检查 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并比对。
