本质是mysql 5.7不识别mysql 8.0新增的基于unicode 9.0的校对规则utf8mb4_0900_ai_ci,而utf8mb4字符集本身在5.7已支持,故只需替换collate值(如改为utf8mb4_unicode_ci),不可降级字符集以免丢失emoji等四字节字符。

MySQL跨版本迁移时,utf8mb4_0900_ai_ci在5.7及更早版本报Unknown collation错误,本质是校对规则不被识别,不是字符集本身的问题。直接降级为utf8会丢emoji和生僻字,必须只动COLLATE,不动CHARACTER SET utf8mb4。
为什么utf8mb4_0900_ai_ci在MySQL 5.7里报错
MySQL 8.0引入的utf8mb4_0900_ai_ci基于Unicode 9.0,而5.7只支持到Unicode 5.2/6.0,内置校对规则最高为utf8mb4_unicode_ci或utf8mb4_general_ci。服务端解析DDL时遇到不认识的COLLATE名称,直接拒绝执行,不会尝试fallback。
-
utf8mb4字符集本身在5.7已支持,无需降级 - 报错只发生在
CREATE TABLE或ALTER TABLE ... COLLATE语句中 - 即使表已存在,
SHOW CREATE TABLE输出里仍会带8.0专属校对规则,导出时默认保留
导出时就规避:用--compatible=mysql57 + --collation-server=utf8mb4_unicode_ci
这是最干净的做法——不让问题进SQL文件。mysqldump从8.0导出给5.7用,必须显式声明兼容目标版本。
-
--compatible=mysql57会自动把utf8mb4_0900_ai_ci替换成utf8mb4_unicode_ci,同时处理其他语法差异(如JSON字段默认值) -
--collation-server=utf8mb4_unicode_ci强制所有新表使用该校对规则,避免依赖服务器默认值 - 两个参数必须一起用:
mysqldump --compatible=mysql57 --collation-server=utf8mb4_unicode_ci --default-character-set=utf8mb4 -u root -p db_name > dump.sql - 注意:
--default-character-set=utf8mb4位置必须靠前,否则会被忽略
导入前手动修复dump文件里的校对规则
如果已经拿到含utf8mb4_0900_ai_ci的SQL文件,别用全局替换utf8mb4为utf8——这会破坏emoji存储能力。
- 只替换校对规则部分:
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' dump.sql - 检查是否还有其他8.0专属规则:
grep -o 'utf8mb4_0900_[^ )]*' dump.sql,常见变体包括utf8mb4_0900_as_cs、utf8mb4_0900_bin,全部替换为对应5.7可用版本(如utf8mb4_unicode_ci、utf8mb4_bin) - 确认
CREATE TABLE语句末尾是DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci,不是utf8mb4_general_ci(该规则在8.0已被标记为deprecated)
导入后验证校对规则是否生效
导入成功不代表校对规则已真正应用。5.7对COLLATE的继承逻辑和8.0不同,容易漏掉字段级定义。
- 查表级校对:
SHOW CREATE TABLE table_name;,确认COLLATE出现在CREATE TABLE语句末尾 - 查字段级校对:
SHOW FULL COLUMNS FROM table_name;,看Collation列是否全为utf8mb4_unicode_ci,而非utf8mb4_0900_ai_ci或空(表示继承表级,但需确认表级确实设了) - 如果字段仍显示旧规则,执行
ALTER TABLE table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;单独修正
最容易被忽略的是:即使SHOW VARIABLES LIKE 'character_set%'全为utf8mb4,只要某个字段的Collation还是utf8mb4_0900_ai_ci,MySQL 5.7在解析该字段时就会报错——它根本不会尝试加载这个规则,而是直接中断语句执行。











