MySQL 8.0移除GRANT隐式建用户、GROUP BY默认排序及SHOW GRANTS稳定格式,需拆分CREATE USER+GRANT、显式ORDER BY、改用information_schema查权限,并显式指定认证插件。

GRANT 不能再自动建用户,必须拆成 CREATE USER + GRANT
MySQL 8.0 彻底移除了 GRANT 隐式创建用户的逻辑,哪怕你开了 NO_AUTO_CREATE_USER 也没用。5.7 下执行 GRANT SELECT ON db.* TO 'u'@'%' IDENTIFIED BY 'p' 能直接建用户+赋权;8.0 执行这句会报 ERROR 1064 (42000),卡在 IDENTIFIED BY 位置。
实操建议:
- 升级脚本里所有带
IDENTIFIED BY的GRANT,必须拆成两步:CREATE USER 'u'@'%' IDENTIFIED BY 'p';+GRANT SELECT ON db.* TO 'u'@'%'; - 跨版本兼容写法:用
CREATE USER IF NOT EXISTS开头,5.7 会忽略IF NOT EXISTS但不报错,8.0 则真正生效 - 别在
GRANT语句里再写IDENTIFIED BY,8.0 语法不认
CREATE USER 必须显式指定认证插件,否则客户端连不上
8.0 默认用 caching_sha2_password 插件,而很多老客户端(如 PyMySQL 0.9、Navicat 旧版、某些 Java JDBC 驱动)不支持它,连接时直接报 Authentication plugin 'caching_sha2_password' cannot be loaded。
实操建议:
- 新建用户时务必显式指定插件:
CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'p'; -
IDENTIFIED WITH和IDENTIFIED BY不能混用;WITH后是插件名,BY后才是密码 - 已有用户改插件用
ALTER USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'p';,注意 5.7 对ALTER USER是静默忽略的
GROUP BY 不再隐式排序,ORDER BY 必须显式写
5.7 中 SELECT a, COUNT(*) FROM t GROUP BY a 返回结果默认按 a 排序;8.0 移除了这个行为,结果顺序不确定,除非加 ORDER BY a。
实操建议:
- 所有含
GROUP BY的查询,如果业务依赖排序,必须补上ORDER BY - 别靠
EXPLAIN或测试数据“猜”顺序,8.0 的优化器可能因统计信息变化改变执行路径 - 升级前用
SELECT @@sql_mode;检查是否含ONLY_FULL_GROUP_BY,它会让非法GROUP BY直接报错
SHOW GRANTS 输出格式变,权限解析脚本容易崩
8.0 的 SHOW GRANTS FOR 'u'@'%' 多了角色行、少了 USAGE 显式声明,且字段顺序和数量不稳定。靠正则从输出里提取权限的运维脚本或比对工具,在 8.0 下大概率失效。
实操建议:
- 避免解析
SHOW GRANTS文本,改用information_schema.role_edges(8.0)或mysql.user表(通用)查权限 - 若必须解析,先查版本:
SELECT VERSION();,再分支处理不同格式 - 不要依赖列顺序,比如
SHOW GRANTS第二列未必是权限字符串,8.0 可能插入角色行打断结构
实际迁移中最容易被忽略的不是语法报错,而是那些“没报错但行为变了”的地方:比如触发器在严格模式下突然中断、utf8mb4_0900_ai_ci 排序规则导致索引范围扫描变慢、或者 INFORMATION_SCHEMA 字段缺失引发元数据同步失败。这些不会让你的 SQL 立刻执行失败,但会在某个低概率请求里悄悄出问题。


















