引言:报错来自mysql5.7升级到mysql8过程
错误一:索引自增异常
报错: Duplicate entry '18486’2025-04-18 08:34:32.661 : Duplicate entry’18406’ for key ‘kd 某表名.PRINARY’
原因: 建表语句导早了,在导建表语句到升级的这段时间后面又多了一些数据,导致自增键增长超过前索引最大值。
解决: SELECT MAX(id) FROM 某表名; --18640
ALTER TABLE 某表名 AUTO_INCREMENT = 18641; --设置为当前最大值 +1。
错误二:索引损坏
报错:
Index 某索引名称 is corrupted
原因:
默认值调整:MySQL 8.0将默认字符集从latin1改为utf8mb4,默认排序规则从latin1_swedish_ci改为utf8mb4_0900_ai_ci。若表或列未显式定义字符集,升级后索引键长度可能因字符集变化而超出限制(如utf8mb4单字符最多占4字节),导致索引损坏。
解决:
– 删除并重建索引(适用于InnoDB引擎)
ALTER TABLE 某表名
DROP INDEX 某索引,
ADD INDEX 某索引 (某字段);
拓展:如何找到所有索引损坏的表然后一并修复呢?
①批量生成check语句:
SELECT CONCAT('CHECK TABLE ', TABLE_NAME, ‘;’)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = ‘数据库名称’;
②执行上面生成的语句
错误三:字符集和排序规则变更
报错:
llegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation ‘find_in_set’
2025-05-07 10:24:39.553
; uncategorized SQLException; SQL state [HY000]; error code [1267]; Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation ‘find_in_set’;
nested exception is java.sql.SQLException: Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation ‘find_in_set’
分析:
SHOW FULL COLUMNS FROM 表名; --查看字段的排序规则
原因:
MySQL 8.0 默认使用 utf8mb4 字符集和 utf8mb4_0900_ai_ci 排序规则,而 MySQL 5.7 默认使用 utf8mb4 和 utf8mb4_general_ci。FIND_IN_SET函数中有两个参数第一个为当前表的字段(默认排序规则为utf8mb4_general_ci),后一个为某临时集合(默认排序规则为utf8mb4_0900_ai_ci),导致排序规则不匹配。
解决:
①将所有表的编码和排序改为mysql8的utf8mb4 字符集和 utf8mb4_0900_ai_ci
ALTER TABLE 某表名
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;
②将所有FIND_IN_SET的地方显示指定编码如:
FIND_IN_SET(某字段, @某临时集合 COLLATE utf8mb4_general_ci))
注意:还需要将生产和测试环境的默认编码设置为一致的。比如生产是旧的utf8mb4_general_ci,测试环境默认建表也要改成这个编码。