MySQL 8.0恢复时出现排序规则冲突如何解决

作者:袖梨 2026-08-22

必须文本替换dump文件中的旧排序规则:将utf8mb4_unicode_520_ci改为utf8mb4_0900_ai_ci,删改CHARSET=utf8mb4 COLLATE=utf8_general_ci等非法组合,并统一库表字段collation为utf8mb4_0900_ai_ci。

恢复时遇到“Unknown collation”错误怎么救

这是从 MySQL 5.7 或更早版本导出的 SQL 文件,在 8.0 中导入时报的典型错误,比如 Unknown collation: 'utf8mb4_unicode_520_ci'COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'utf8mb4'。根本原因是 dump 文件里硬编码了 8.0 不认识的旧排序规则,或者把已废弃的 utf8 字符集写进了建表语句。

  1. 先用文本编辑器或 sed 批量替换:把所有 utf8mb4_unicode_520_ci 换成 utf8mb4_0900_ai_ci
  2. 删掉或重写所有含 CHARSET=utf8mb4 COLLATE=utf8_general_ci 的行——utf8_general_ci 在 utf8mb4 字符集下根本不合法,必须改为 utf8mb4_0900_ai_ciutf8mb4_unicode_ci
  3. 如果 dump 文件里有 CREATE DATABASE ... DEFAULT CHARSET=utf8,要改成 DEFAULT CHARSET=utf8mb4,否则 8.0 会拒绝解析

还原后报 ERROR 1267:Illegal mix of collations 怎么定位

导入成功但一查就崩,说明字段级 collation 混用了。MySQL 8.0 对 JOIN、FIND_IN_SET()、子查询等操作强制校验两边 collation 是否一致,不匹配就直接报错,不会静默转换。

  1. 执行 SELECT TABLE_NAME, COLUMN_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND COLLATION_NAME NOT IN ('utf8mb4_0900_ai_ci');,找出所有非 8.0 默认的列
  2. 特别注意 FIND_IN_SET() 的两个参数:第一个是字段(可能带旧 collation),第二个是变量或字符串字面量(默认继承 session 的 collation,通常是 utf8mb4_0900_ai_ci)——两边不一致就会触发错误
  3. JSON_VALUE() 也一样,必须显式声明返回类型和 collation,比如 JSON_VALUE(data, '$.field' RETURNING CHAR(100) COLLATE utf8mb4_0900_ai_ci)

ALTER TABLE CONVERT TO 和 MODIFY 到底该用哪个

CONVERT TO 改的是整张表的默认 collation,但不会覆盖已有字段上显式声明的旧 collation;MODIFY 是精准修正单个字段,必须带完整类型定义。

  1. 先跑 ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;,它会让新字段继承这个 collation,但对已有字段中显式写了 COLLATE utf8mb4_general_ci 的列无效
  2. 再针对这些“钉子户”字段单独执行:ALTER TABLE t MODIFY col VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
  3. TEXT 类型字段也要查 —— 它们同样能带 collation,且参与比较,漏掉会导致后续 JOIN 失败
  4. 大表操作前加 SET SESSION innodb_lock_wait_timeout = 300;,避免 phpMyAdmin 或宝塔面板超时中断

UNIQUE 索引突然失效或报 Duplicate entry 怎么办

同一字符串在 utf8mb4_general_ciutf8mb4_0900_ai_ci 下可能被判定为“相等”或“不等”,导致唯一约束行为突变。这不是数据错了,是 collation 切换后比较逻辑变了。

  1. 还原后立刻验证关键索引字段的行为:SELECT * FROM t WHERE col = '张三' COLLATE utf8mb4_unicode_ci;COLLATE utf8mb4_0900_ai_ci 结果是否一致
  2. 如果源库用的是 utf8mb4_bin 建的 UNIQUE 索引,目标库却按 utf8mb4_0900_ai_ci 解析,小写/大写可能被当成不同值,插入时就会撞车
  3. 修复方式不是删索引重挂,而是先统一字段 collation,再 ALTER TABLE t DROP INDEX idx_name; ALTER TABLE t ADD UNIQUE INDEX idx_name (col);

真正麻烦的不是改 collation 这一步,而是你得确认业务 SQL 里所有隐式比较点——比如 ORDER BYGROUP BY、视图定义、存储过程里的临时表——它们全依赖 collation 行为。一个没扫到,上线就出数据逻辑偏差。

相关文章

精彩推荐