mysql角色权限生效需三步全做对:创建角色、授予权限、设为默认角色;版本须≥8.0.1,activate_all_roles_on_login需on,role_admin权限不可少,角色名勿用反引号,grant后须set default role激活,show grants不显示继承权限,权限变更需重连或set role刷新。

因为角色把重复的权限组合打包成可复用单元,改一次角色权限,所有绑定用户自动继承——但前提是三步全做对:创建角色、授予权限、设为默认角色。漏掉任一环节,就只是“看起来授权了”,实际查表照样报 ERROR 1142。
CREATE ROLE 报 ERROR 1064 或 ERROR 3719 怎么办
这不是语法错,是版本或配置卡点:
- 先跑
SELECT VERSION();—— 输出必须是8.0.1或更高;5.7.x或8.0.0直接不支持CREATE ROLE - 确认全局变量已开:
SELECT @@activate_all_roles_on_login;必须返回ON,否则即使建成功也会报ERROR 3719 - 检查当前用户是否有
ROLE_ADMIN权限:SHOW GRANTS;里得有GRANT ROLE_ADMIN ON *.*,不然连GRANT 'role_x' TO 'user'都被拒绝 - 别用反引号包角色名:
CREATE ROLE `app_reader`是错的,应写成CREATE ROLE 'app_reader'或CREATE ROLE app_reader
GRANT 了角色,用户还是没权限
这是线上最常误判的问题:GRANT 只是“挂载”,不是“启用”。用户登录后默认角色处于未激活状态,CURRENT_ROLE() 返回 NONE 就是铁证。
- 必须显式执行:
SET DEFAULT ROLE 'app_reader' TO 'user1'@'%'; - 若用连接池(如 HikariCP),需额外配置:
sessionVariables=default_role=app_reader或connection-init-sql="SET DEFAULT ROLE 'app_reader'" - 别依赖
GRANT 'app_reader' TO 'user1'@'%'就以为完事——这步只建立绑定关系,不触发权限加载 - 用户有多个角色时,
SET DEFAULT ROLE ALL TO虽方便,但违反最小权限原则,生产环境慎用
SHOW GRANTS 看不到角色权限,是不是没授成功
不是失败,是设计如此。SHOW GRANTS FOR 'user'@'%' 只显示直接授予用户的权限(比如 USAGE),完全不展开角色继承的权限。
- 查角色内具体权限:用
SHOW GRANTS FOR 'app_reader'; - 查某用户通过某角色获得的权限:用
SHOW GRANTS FOR 'user1'@'%' USING 'app_reader'; - 验证当前会话是否生效:登录后执行
SELECT CURRENT_ROLE();,返回非NONE才算真正激活 - 审计时如果只扫
SHOW GRANTS输出,可能把拥有 DBA 权限的账号当成“仅能连接”,风险极大
真正容易被忽略的是权限缓存机制:哪怕你刚 GRANT SELECT ON new_table TO 'app_reader',已连着的会话仍查不到新表——必须重连,或在当前会话手动 SET ROLE 'app_reader'; 才能刷新上下文。











