MySQL 5.7升级8.0后出现排序规则问题的解决方案汇总 |
比较操作中使用不同的字符集或排序规则通常会触发此问题,MySQL 8.0 默认 COLLATE 为 问题现象MySQL 5.7.34 升级到 8.0.32 后部分查询语句报错如下: ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation 'find_in_set' 问题原因比较操作中使用不同的字符集或排序规则通常会触发此问题,MySQL 8.0 默认 COLLATE 为 问题重现过程创建测试表 。 CREATE TABLE `t01` ( `ID` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `A_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `B_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`ID`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 执行查询语句 。 SELECT AAA.* FROM( SELECT @xxx AS _xxx, ( SELECT @xxx := GROUP_CONCAT( A_CODE ) FROM t01 WHERE FIND_IN_SET( B_CODE, @xxx ) ) AS cxxx FROM t01,( SELECT @xxx := 'xxx') b WHERE @xxx IS NOT NULL) ID,t01 AAA WHERE FIND_IN_SET( AAA.A_CODE, ID._xxx ) order by A_CODE; 报错 。 ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation 'find_in_set' 问题分析查看默认排序规则 。 mysql> show collation like 'utf8mb4_0900_ai_ci'; +--------------------+---------+-----+---------+----------+---------+---------------+ | Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | +--------------------+---------+-----+---------+----------+---------+---------------+ | utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD | +--------------------+---------+-----+---------+----------+---------+---------------+ 1 row in set (0.00 sec) mysql> show collation like 'utf8mb4_general_ci'; +--------------------+---------+----+---------+----------+---------+---------------+ | Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | +--------------------+---------+----+---------+----------+---------+---------------+ | utf8mb4_general_ci | utf8mb4 | 45 | | Yes | 1 | PAD SPACE | +--------------------+---------+----+---------+----------+---------+---------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.COLLATIONS WHERE IS_DEFAULT='Yes' and CHARACTER_SET_NAME='utf8mb4'; +--------------------+--------------------+-----+------------+-------------+---------+---------------+ | COLLATION_NAME | CHARACTER_SET_NAME | ID | IS_DEFAULT | IS_COMPILED | SORTLEN | PAD_ATTRIBUTE | +--------------------+--------------------+-----+------------+-------------+---------+---------------+ | utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD | +--------------------+--------------------+-----+------------+-------------+---------+---------------+ 1 row in set (0.00 sec) 查看相关参数 。 mysql> show variables like '%collation%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_0900_ai_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.00 sec) 其中: mysql> show global variables like '%collation%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.00 sec) 查看配置文件参数 。 mysql@CJC-DB-01:/home/mysql$cat /etc/my.cnf ...... [mysqld] collation_server = utf8mb4_general_ci 可以看到,客户端局部会话变量 collation_connection 的值为 这是由于服务端在客户端连接时,获取了客户端对字符集和排序规则的缺省设置,也就是 解决方案
1. 修改参数参数 --character-set-client-handshake Command-Line Format:--character-set-client-handshake[={OFF|ON}] Deprecated:8.0.35 Type:Boolean Default Value:ON 参数说明
此选项在 MySQL 8.0.35 及更高版本的 MySQL 8.0 中已被弃用 。在该版本中,无论何时使用此选项,都会发出警告,并将在未来版本的 MySQL 中删除 。 依赖此选项的应用程序应该尽快开始迁移 。 添加 my.cnf 参数 。 [mysqld] skip-character-set-client-handshake 重启 MySQL 。 mysqladmin -uroot -p****** shutdown mysqld --defaults-file=/etc/my.cnf --user=mysql & 登录 mysql -uroot -p cjc 查看参数,collation_connection 参数值修改成功 mysql> show global variables like '%collation%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.00 sec) mysql> show variables like '%collation%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.01 sec) 再次执行,问题解决 。 SELECT AAA.* FROM( SELECT @xxx AS _xxx, ( SELECT @xxx := GROUP_CONCAT( A_CODE ) FROM t01 WHERE FIND_IN_SET( B_CODE, @xxx ) ) AS cxxx FROM t01,( SELECT @xxx := 'xxx') b WHERE @xxx IS NOT NULL) ID,t01 AAA WHERE FIND_IN_SET( AAA.A_CODE, ID._xxx ) order by A_CODE; Empty set, 2 warnings (0.00 sec) 2. 修改表 COLLATE先改回原参数,查询报错 。 SELECT AAA.* FROM( SELECT @xxx AS _xxx, ( SELECT @xxx := GROUP_CONCAT( A_CODE ) FROM t01 WHERE FIND_IN_SET( B_CODE, @xxx ) ) AS cxxx FROM t01,( SELECT @xxx := 'xxx') b WHERE @xxx IS NOT NULL) ID,t01 AAA WHERE FIND_IN_SET( AAA.A_CODE, ID._xxx ) order by A_CODE; ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation 'find_in_set' 修改表排序规则 。 mysql> show create table t01G; *************************** 1. row *************************** Table: t01 Create Table: CREATE TABLE `t01` ( `ID` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `A_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `B_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`ID`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC 1 row in set (0.00 sec) ERROR: No query specified 修改所有列 COLLATE,实际上只修改 ALTER TABLE cjc.t01 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; ALTER TABLE cjc.t01 MODIFY COLUMN `ID` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL; ALTER TABLE cjc.t01 MODIFY COLUMN `A_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL; ALTER TABLE cjc.t01 MODIFY COLUMN `B_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL; 再次执行,问题解决 。 SELECT AAA.* FROM( SELECT @xxx AS _xxx, ( SELECT @xxx := GROUP_CONCAT( A_CODE ) FROM t01 WHERE FIND_IN_SET( B_CODE, @xxx ) ) AS cxxx FROM t01,( SELECT @xxx := 'xxx') b WHERE @xxx IS NOT NULL) ID,t01 AAA WHERE FIND_IN_SET( AAA.A_CODE, ID._xxx ) order by A_CODE; Empty set, 2 warnings (0.00 sec) 查看表结构 。 mysql> show create table t01G; *************************** 1. row *************************** Table: t01 Create Table: CREATE TABLE `t01` ( `ID` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `A_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `B_CODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, PRIMARY KEY (`ID`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC 1 row in set (0.00 sec) 3. 修改 SQL 语句将 改写后的SQL如下: SELECT AAA.* FROM( SELECT @xxx AS _xxx, ( SELECT @xxx := GROUP_CONCAT( A_CODE COLLATE utf8mb4_0900_ai_ci ) FROM t01 WHERE FIND_IN_SET( B_CODE COLLATE utf8mb4_0900_ai_ci, @xxx ) ) AS cxxx FROM t01,( SELECT @xxx := 'xxx') b WHERE @xxx IS NOT NULL) ID,t01 AAA WHERE FIND_IN_SET( AAA.A_CODE COLLATE utf8mb4_0900_ai_ci, ID._xxx ) order by A_CODE; 总结比较三种解决方案,每种解决方案适用场景不同,请根据实际情况选择解决方案 。
以上就是MySQL 5.7升级8.0后出现排序规则问题的解决方案汇总的详细内容,更多关于MySQL 5.7升级8.0排序规则问题的资料请关注其它相关文章! |