MySQL 8.0 中 GRANT 语句不能再创建用户或设密码,因其彻底移除 IDENTIFIED BY 语法,必须先 CREATE USER(建议显式指定 mysql_native_password 插件)再 GRANT 授权,否则报 ERROR 1064 或 1410。

GRANT 语句在 MySQL 8.0 中不能再创建用户——这不是 bug,而是强制拆分认证与授权的底层设计变更。直接写 GRANT ... IDENTIFIED BY 必然报错,常见错误是 ERROR 1064 (42000) 或 ERROR 1410 (42000)。
为什么 GRANT 里带 IDENTIFIED BY 会语法报错
MySQL 8.0 彻底移除了 GRANT 语句中 IDENTIFIED BY 的语法支持。服务器解析时根本不会识别这个子句,直接抛出 ERROR 1064。这不是配置或权限问题,是语法层面被删了。
-
ERROR 1064:说明 SQL 解析失败,IDENTIFIED BY出现在不该出现的位置 -
ERROR 1410:说明当前账户没有“在授予权限时顺手建用户”的权限(哪怕你是root) - 旧脚本里类似
GRANT SELECT ON db.* TO 'u'@'%' IDENTIFIED BY 'p'的写法,必须手动拆成两行
CREATE USER 必须显式指定认证插件
MySQL 8.0 默认用 caching_sha2_password 插件,但很多客户端(如老版本 Navicat、DBeaver、PHP mysqli)不兼容,连不上就会卡在 Authentication failed。
- 安全起见,建议显式指定兼容插件:
CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'p' - 不写
IDENTIFIED WITH就默认用caching_sha2_password,容易导致外部连接失败 -
'u'@'localhost'和'u'@'%'是两个完全独立的用户,权限不能互通
授权后要不要执行 FLUSH PRIVILEGES
绝大多数情况不需要。MySQL 8.0 的权限系统是实时生效的,CREATE USER 和 GRANT 语句本身就会立即写入权限表并加载到内存。
- 只有在绕过 SQL 接口、直接
UPDATE mysql.user等非常规操作后,才需要FLUSH PRIVILEGES - 执行它不会报错,但属于冗余操作;如果权限没生效,真正原因通常是 host 写错、用户不存在,或客户端复用旧连接
角色(ROLE)不是可选项,而是管理复杂权限的刚需
当多个用户需要相同权限集(比如 5 个开发都要 SELECT, INSERT on orders),逐个 GRANT 就是技术债。角色把权限打包成可复用单元。
- 角色名也必须带 host,例如
'dev_rw'@'%',否则后续绑定会失败 -
SET ROLE是会话级激活,不执行就看不到效果;要用SET DEFAULT ROLE才能让登录后自动生效 - 角色权限是并集,不是覆盖——用户已有权限 + 角色权限 = 实际权限
实际迁移时最容易漏掉的点:host 精确匹配、认证插件兼容性、角色 host 后缀、以及误以为 FLUSH PRIVILEGES 是必需步骤。这些不是“高级技巧”,而是 MySQL 8.0 权限模型的基本运行前提。


















