mysql 8.0 彻底禁止 grant 隐式建用户且默认认证插件变为 caching_sha2_password,导致 grant 中含 identified by 报错、旧客户端连接失败;必须显式 create user 指定 mysql_native_password 插件,并在 alter user 时始终带插件名以防静默切换。

MySQL 5.7 和 8.0 在用户授权语法上不是“略有调整”,而是存在**不可忽略的语法断裂**:8.0 彻底禁止 GRANT 隐式建用户,且默认认证插件变更直接导致旧客户端连接失败——哪怕 SQL 语句本身能执行成功。
GRANT 语句里写 IDENTIFIED BY 就会报错
这是最常踩的第一道墙。MySQL 8.0 的 GRANT 语句不再接受 IDENTIFIED BY 或 IDENTIFIED WITH 子句,哪怕用户还不存在。
- 5.7 可以跑通:
GRANT SELECT ON app.* TO 'api'@'%' IDENTIFIED BY 'p123'; - 8.0 执行直接报错:
ERROR 1064 (42000): You have an error in your SQL syntax [...] near 'IDENTIFIED BY' - 这不是配置问题,是语法解析器硬性拒绝——
sql_mode里的NO_AUTO_CREATE_USER在 8.0 已无意义 - 必须拆成两步:
CREATE USER 'api'@'%' IDENTIFIED BY 'p123';→GRANT SELECT ON app.* TO 'api'@'%';
CREATE USER 必须显式指定 mysql_native_password 才能兼容老客户端
8.0 默认用 caching_sha2_password 插件存密码,但 PyMySQL、旧版 PHP mysqli、某些 Node.js MySQL 驱动根本不认识它,连接时抛出 Authentication plugin 'caching_sha2_password' cannot be loaded。
- 错误写法(看着像对,实则埋雷):
CREATE USER 'app'@'%' IDENTIFIED BY 'pwd'; - 正确写法(明确指定插件):
CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'; -
IDENTIFIED WITH和IDENTIFIED BY必须同时出现,顺序不能颠倒;BY后才是密码,WITH后才是插件名 - 如果后续要切回
caching_sha2_password,得用ALTER USER 'app'@'%' IDENTIFIED WITH caching_sha2_password BY 'pwd';,不能只改plugin字段
ALTER USER IDENTIFIED BY 会悄悄覆盖认证插件
这个行为在 8.0 中极易被忽视:即使你用 mysql_native_password 创建的用户,只要执行一次 ALTER USER ... IDENTIFIED BY,插件就会被重置为默认的 caching_sha2_password,导致已有应用突然连不上。
- 创建时用了兼容插件:
CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'p'; - 后来只改密码:
ALTER USER 'u'@'%' IDENTIFIED BY 'newp'; - 结果:
SELECT plugin FROM mysql.user WHERE user='u';返回caching_sha2_password—— 不报错,但连接断了 - 安全做法是始终带上插件:
ALTER USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'newp'; - 5.7 下
ALTER USER不支持插件指定,所以跨版本脚本里不能依赖该语句统一处理
真正麻烦的不是语法写不对,而是语法写对了却连不上——因为 CREATE USER 和 ALTER USER 对认证插件的隐式行为,在 5.7 和 8.0 中完全不一致,且没有警告提示。











