mysql 8.0强制拆分用户创建与授权:必须先create user再grant,禁止在grant中使用identified by,否则触发error 1410或1064;create user负责身份认证(含插件、密码策略),grant仅管控权限。

MySQL 8.0 禁止 GRANT 创建用户,不是 bug,是强制拆分设计 —— 你写的 GRANT ... TO 'u'@'%' IDENTIFIED BY 'p' 语法直接被拒绝,不报密码错、不报权限错,就是“不认”。
ERROR 1410 和 ERROR 1064 都指向同一个事实
只要你在 GRANT 里写了 IDENTIFIED BY,就会触发错误:
-
ERROR 1064 (42000):语法解析阶段就失败,MySQL 根本不接受这种结构 -
ERROR 1410 (42000):语句能解析但语义违规,明确告诉你 “You are not allowed to create a user with GRANT”
两者本质一致:MySQL 8.0 彻底移除了 GRANT 的用户创建能力。这不是兼容性开关,也不是配置能绕过,是 parser 层硬拦截。
CREATE USER 和 GRANT 各管什么,不能混
旧版把「身份」和「权限」塞进一条语句,8.0 要求显式分离:
-
CREATE USER负责:用户名、主机名、密码、认证插件(如caching_sha2_password)、密码过期策略、账户锁定状态 -
GRANT只负责:数据库/表/列/函数等对象上的具体权限动作,不碰密码、不改插件、不设生命周期策略
比如你想用 mysql_native_password 兼容老客户端,必须在 CREATE USER 里写明:CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'p';GRANT 中加这个会直接报错。
容易漏掉的三个执行细节
即使语法全对,仍可能卡在实际生效环节:
- 用户已存在时,
CREATE USER会报ERROR 1396,此时该用ALTER USER 'u'@'%' IDENTIFIED BY 'p',不是重试CREATE -
GRANT后不执行FLUSH PRIVILEGES,部分权限变更(尤其是涉及PROXY或角色默认激活)可能延迟生效 - 授予角色后,用户登录不会自动获得权限 —— 必须显式执行
SET DEFAULT ROLE 'role_name'@'%',否则SHOW GRANTS看得到绑定,但实际查询会Access denied
最常被跳过的其实是认证插件匹配问题:你用默认 caching_sha2_password 创建了用户,但应用用的是旧版 JDBC 驱动(8.0 之前),连接时只显示 “Access denied”,根本不会提示插件不兼容。这时候得回退到 CREATE USER ... IDENTIFIED WITH mysql_native_password BY ...,而不是反复调密码或改 host。











