使用 --compatible 参数可使 mysqldump 生成兼容低版本的 SQL,如 --compatible=mysql40;但需配合 --skip-triggers、--no-tablespaces 等选项,并手动替换 JSON 类型、排序规则、隐藏主键等高版本语法。

mysqldump 导出时指定兼容版本参数
MySQL 5.7 和 8.0 的默认 SQL 模式、保留字、JSON 字段处理方式差异较大,直接用高版本 mysqldump 导出再导入低版本会报错,比如 Unknown column 'json_col' in 'field list' 或 You have an error in your SQL syntax。关键不是“能不能导”,而是导出的 SQL 是否带目标版本不支持的语法。
使用 --compatible 参数可强制降级语法输出:
mysqldump --compatible=mysql40 --skip-triggers --no-tablespaces -u root -p mydb > mydb.sql
常用值有:mysql40(兼容 4.0+)、ansi(ANSI SQL 标准)、postgresql(仅语法适配,不推荐)。注意:--compatible 不影响数据类型映射,比如 MySQL 8.0 的 JSON 类型仍会导出为 JSON,需手动替换成 TEXT 并关闭校验。
-
--skip-triggers避免触发器中使用NEW.col等 5.7+ 才支持的写法 -
--no-tablespaces防止导出TABLESPACE子句(MySQL 5.7 默认禁用) - 不要加
--set-gtid-purged=ON(8.0 默认开启),低版本不识别该语句
导入前手动清理高版本特有语法
即使用了 --compatible,某些结构仍无法自动降级:比如 MySQL 8.0 的隐藏主键(INVISIBLE PRIMARY KEY)、角色权限语句(CREATE ROLE)、默认字符集 utf8mb4_0900_as_cs。导入时会卡在第一条非法语句并报错退出。
建议用 sed 或脚本预处理 SQL 文件:
sed -i 's/INVISIBLE //g; s/ALGORITHM=INSTANT//g; s/utf8mb4_0900_as_cs/utf8mb4_general_ci/g' mydb.sql
重点检查并替换以下内容:
-
CREATE TABLE ... JSON→ 改为TEXT并删除JSON_VALID()约束 -
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP→ 拆成两个独立子句(5.6 不支持复合写法) - 所有
ROLE、SET PERSIST、ADMIN OPTION相关语句整行删除 -
ENGINE=InnoDB ROW_FORMAT=DYNAMIC中的ROW_FORMAT可删(5.6 默认 DYNAMIC,但不认该关键字)
字符集与排序规则必须显式降级
MySQL 8.0 默认字符集是 utf8mb4,排序规则是 utf8mb4_0900_as_cs;而 5.7 最高只支持 utf8mb4_unicode_ci。如果导出 SQL 中保留了 8.0 的排序规则,导入时会提示 Unknown collation: 'utf8mb4_0900_as_cs',且不会跳过,直接中断。
不能依赖 --default-character-set=utf8mb4,它只影响客户端连接,不改表定义中的 COLLATE。必须全局替换:
sed -i "s/utf8mb4_0900_as_cs/utf8mb4_unicode_ci/g; s/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g" mydb.sql
同时确认目标库已启用 utf8mb4 支持:
SET NAMES utf8mb4; ALTER DATABASE mydb CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
否则即使 SQL 通过,插入中文可能乱码或截断。
权限迁移需重建而非导出
mysqldump --all-databases 不导出 mysql 系统库(除非显式加上),而权限信息全在 mysql.user、mysql.db 表里。即便你 dump 了系统库,MySQL 8.0 的 authentication_string 字段加密方式(caching_sha2_password)和 5.7(mysql_native_password)不兼容,直接导入会导致用户无法登录。
正确做法是:在目标低版本上,用 SHOW CREATE USER 和 SHOW GRANTS 生成可执行语句,再手动调整认证插件:
CREATE USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'; GRANT SELECT,INSERT ON mydb.* TO 'appuser'@'%';
要点:
- 避免用
mysqldump mysql迁移权限,风险极高 - 8.0 用户若用
caching_sha2_password,必须在创建时显式指定IDENTIFIED WITH mysql_native_password - 导入后执行
FLUSH PRIVILEGES,否则新权限不生效
版本降级迁移最易忽略的是隐式行为变更:比如 8.0 中 GROUP BY 默认严格,5.7 允许 select 列不在 group by 中;又比如 8.0 的 ONLY_FULL_GROUP_BY 开关位置变了。这些不会报错,但查询结果可能不一致——得靠业务验证,不能只看导入成功。










