MySQL 8.0中GRANT语句禁止出现IDENTIFIED BY,解析器在语法层硬性拒绝,必报ERROR 1064;必须先CREATE USER(显式指定插件和密码),再GRANT授予权限,二者严格分离且不可颠倒顺序。

GRANT 语句里写 IDENTIFIED BY 就会报错
这不是你权限不够,也不是 SQL mode 没关对,而是 MySQL 8.0 的解析器压根不认 IDENTIFIED BY 出现在 GRANT 语句里。只要出现,就立刻触发 ERROR 1064 (42000),错误位置基本卡在 IDENTIFIED 关键字附近。
旧写法(5.7 可用):GRANT SELECT ON mydb.* TO 'u'@'%' IDENTIFIED BY 'p'
8.0 执行直接失败,连语义检查都进不去 —— 语法层就被拦了。
- 哪怕你是
root用户,sql_mode全关,也绕不过去 -
NO_AUTO_CREATE_USER在 8.0 已被移除,设了也没用 - 不是 bug,是 parser 层硬编码拒绝,代码级移除
必须拆成 CREATE USER + GRANT 两步执行
MySQL 8.0 强制把「身份认证」和「权限控制」解耦:前者归 CREATE USER 管,后者只归 GRANT 管。少一步都不行,顺序也不能颠倒。
- 第一步:用
CREATE USER注册账户,必须带密码和插件声明,例如:CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'p' - 第二步:用
GRANT授予权限,严禁再出现IDENTIFIED BY或IDENTIFIED WITH,例如:GRANT SELECT ON mydb.* TO 'u'@'%' - 重复执行
CREATE USER会报ERROR 1396,此时该用ALTER USER 'u'@'%' IDENTIFIED BY 'newp'改密
认证插件不显式指定,连得上但认证失败
即使上面两步全对,客户端仍可能报 Access denied 或 Authentication plugin 'caching_sha2_password' cannot be loaded —— 这不是权限问题,是握手阶段就断了。
- 8.0 默认用
caching_sha2_password,但 PyMySQL 0.9、旧版 Navicat、某些 JDBC 驱动不支持它 - 创建用户时必须显式写
IDENTIFIED WITH mysql_native_password BY 'p',WITH和BY缺一不可 -
ALTER USER 'u'@'%' IDENTIFIED BY 'p'会悄悄把插件重置为caching_sha2_password,已有应用可能突然连不上
host 字段不一致是最容易被跳过的坑
'u'@'localhost' 和 'u'@'%' 是两个完全独立的用户,SHOW GRANTS FOR 'u'@'%' 查不到前者的权限,GRANT 时 host 不匹配就会报 ERROR 1410,提示 “not allowed to create a user”,其实只是查不到目标记录。
- Navicat 默认存
'u'@'%',命令行连本地却写'u'@'127.0.0.1',也查不到 - 确认真实记录用:
SELECT user, host FROM mysql.user WHERE user = 'u' - 修复只能新建匹配的用户,或用
UPDATE mysql.user SET host = '%' WHERE user = 'u' AND host = 'localhost'+FLUSH PRIVILEGES
实际执行时最容易漏掉的是三件事:host 必须完全一致、插件必须显式指定、CREATE USER 和 GRANT 必须分步且不可合并。语法对了不等于能连上,认证链路断在哪儿,往往得从第一个 CREATE USER 开始查。


















