MySQL 8.0 禁止 GRANT 创建用户,是 parser 层硬拦截:ERROR 1064 表示语法非法(IDENTIFIED BY 不属 GRANT 子句),ERROR 1410 表示语义违规(禁止授予权限时建用户);必须先 CREATE USER(设身份、插件、密码),再 GRANT(仅赋权限)。

GRANT 在 MySQL 8.0 中根本不再支持创建用户,这不是语法写错或权限不够,而是 parser 层硬性拒绝 —— 只要你在 GRANT 里写了 IDENTIFIED BY,就会触发 ERROR 1064 或 ERROR 1410。
ERROR 1064 和 ERROR 1410 到底在报什么
这两个错误看起来不同,但指向同一个事实:MySQL 8.0 的 SQL 解析器压根不接受 GRANT ... TO 'u'@'%' IDENTIFIED BY 'p' 这种结构。
-
ERROR 1064 (42000):发生在语法解析阶段,说明语句结构非法 ——IDENTIFIED BY不再是GRANT语句的合法子句 -
ERROR 1410 (42000):语句能被解析,但语义违规,明确告诉你You are not allowed to create a user with GRANT - 哪怕你是
root,哪怕sql_mode全关,也绕不过去 —— 这不是配置开关,是代码级移除
CREATE USER 和 GRANT 各自管什么
MySQL 8.0 强制把「身份认证」和「权限控制」拆成两个不可合并的操作:
-
CREATE USER负责:用户名、host、密码、认证插件(如caching_sha2_password)、密码策略、账户锁定状态 -
GRANT只负责:对库/表/列/函数等对象的具体权限动作,不碰密码、不改插件、不设生命周期 - 比如你想用老客户端连接,必须在
CREATE USER里显式写IDENTIFIED WITH mysql_native_password BY 'p';放到GRANT里直接报错
为什么你执行了 GRANT 还连不上
即使语法全对,仍可能卡在实际生效环节,常见盲区有三个:
- 用户已存在时,重复执行
CREATE USER会报ERROR 1396,此时该用ALTER USER 'u'@'%' IDENTIFIED BY 'p',不是重试CREATE USER - 授予角色后,
GRANT 'role' TO 'u'@'%'只是绑定,不激活 —— 必须额外执行SET DEFAULT ROLE 'role' TO 'u'@'%',否则CURRENT_ROLE()是NULL,权限不可用 - 认证插件不匹配:用默认
caching_sha2_password创建了用户,但 JDBC 驱动版本太旧,连接只报Access denied,不会提示插件问题 —— 得回退到CREATE USER ... IDENTIFIED WITH mysql_native_password
最容易被跳过的其实是 host 精确匹配和插件选择。写 'u'@'%' 和 'u'@'localhost' 是两个完全独立的用户,连 SHOW GRANTS FOR 'u'@'%' 都查不到另一个的权限。而插件选错,连密码都输对了也进不去。


















