mysqldump在mysql创新版与lts版间直接迁移会失败,因语法(如json_table)、sql_mode、系统表结构、认证插件等存在不兼容;可行方案为降级导出或中间格式转换,需规避新版特性并统一字符集与时区。

不能直接逻辑迁移。MySQL创新版(如8.4、9.0等预发布/实验性版本)与LTS版(5.7、8.0)之间存在大量不兼容变更,mysqldump导出后在LTS版导入大概率失败,尤其是涉及JSON_TABLE、SKIP LOCKED增强语法、新系统表结构、默认caching_sha2_password认证插件等。
为什么 mysqldump 导出会失败
创新版的SQL解析器允许许多LTS版根本不识别的语法和函数:
-
SELECT * FROM JSON_TABLE(...)在 8.0.33 之前完全不存在,导入时直接报ERROR 1305 (42000): FUNCTION json_table does not exist - 创新版默认启用
sql_mode = 'STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY,...中新增的约束项,而8.0可能未定义这些模式值,导致SET sql_mode=...语句执行失败 -
INFORMATION_SCHEMA视图字段名或返回结构已变更(如INNODB_METRICS新增列),mysqldump --routines生成的存储过程若引用这些字段,会在LTS版报错 - 用户表
mysql.user中新增字段(如account_locked、password_last_changed)在5.7或早期8.0中不存在,--routines+--triggers导出的权限语句会因字段缺失而中断
可行路径只有两个:降级导出 or 中间格式转换
必须绕过创新版本身的SQL层,从数据物理层或协议层提取“干净”的LTS兼容内容:
- 用
mysqlpump(如果创新版支持)替代mysqldump,它对新版特性有更明确的兼容控制,加--skip-definer --skip-triggers --skip-routines --set-gtid-purged=OFF可避开大部分语法陷阱 - 改用
SELECT ... INTO OUTFILE逐表导出纯数据(CSV/TSV),再用LOAD DATA INFILE导入目标LTS库——但需手动处理ENUM/SET值映射、TIMESTAMP时区偏移、BLOB编码等细节 - 若源库开启
binlog_format = ROW,可用mysqlbinlog --base64-output=DECODE-ROWS解析出原始DML,过滤掉DDL和创新版特有事件,再重放至LTS库(适合增量同步场景)
字符集和时区必须提前对齐
创新版默认character_set_server = utf8mb4且collation_server = utf8mb4_0900_ai_ci,而8.0.30以下LTS版最高只认utf8mb4_0800_ci_as,5.7则根本不支持_0900_*系列排序规则:
- 导出前在创新版执行:
ALTER DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;,并确保每张表也显式指定该排序规则 - 目标LTS库的
my.cnf中必须设character-set-server=utf8mb4和collation-server=utf8mb4_unicode_ci,重启生效 - 时区不一致会导致
TIMESTAMP列值漂移,创新版默认system_time_zone可能为UTC,而LTS库为CST,迁移前统一设为+08:00并验证SELECT NOW()输出是否一致
最常被忽略的是innodb_page_size和redo log配置差异——创新版可能默认启用innodb_page_size=64K或innodb_redo_log_capacity新参数,这些在LTS版无法识别,物理备份(xtrabackup)完全不可用。只能走逻辑层,且必须接受部分功能降级。











