MySQL 8.0 角色无真正继承,仅支持权限叠加且禁循环引用;新建角色默认无权限,需显式 GRANT;角色名区分大小写;SET DEFAULT ROLE 应显式指定而非 ALL;权限变更对旧会话不生效,须重连或 SET ROLE。

MySQL 8.0 没有真正的“角色继承”机制,所谓“继承”只是通过 GRANT role_a TO role_b 实现的权限叠加,且不支持循环引用;误用会直接报错 ERROR 3530 (HY000),不是配置问题,是语法限制。
CREATE ROLE 后必须显式 GRANT 权限,否则角色是空壳
新建的 app_reader 角色默认没有任何权限,连 SELECT 都不能执行。常见错误是建完角色就急着分配给用户,结果用户登录后仍报 ERROR 1142 (42000): SELECT command denied。
-
CREATE ROLE 'app_reader';只创建一个空容器,不带任何能力 - 必须紧跟
GRANT SELECT ON myapp.* TO 'app_reader';才真正赋予权限 - 列级授权也支持:
GRANT SELECT(id, name) ON users TO 'app_reader'; - 角色名区分大小写,
'AppReader'和'appreader'是两个不同角色
GRANT role_to_role 不等于自动继承,而是权限叠加
MySQL 8.0 允许把一个角色授给另一个角色(GRANT r2 TO r1),但这不是面向对象式的“继承”,而是把 r2 的权限合并进 r1 的权限集——r1 拥有自身 + r2 的全部权限,且无法取消其中某一部分。
- 合法操作:
CREATE ROLE 'readonly'; CREATE ROLE 'dev'; GRANT 'readonly' TO 'dev'; - 禁止循环:
GRANT dev TO readonly;会触发ERROR 3530 (HY000): Cannot grant role 'dev' to 'readonly': circular reference detected - 嵌套层级无硬性限制,但超过 3 层易导致权限审计困难
-
SHOW GRANTS FOR 'dev'不显示readonly的内容,需用SHOW GRANTS FOR 'dev' USING 'readonly'单独查
SET DEFAULT ROLE ALL TO user 是最危险的批量激活方式
给用户设 SET DEFAULT ROLE ALL TO 'alice'@'%' 看似省事,实则违反最小权限原则:一旦某个角色被意外授予高危权限(如 DROP DATABASE),所有带 ALL 的用户立即暴露风险。
- 推荐显式列出角色:
SET DEFAULT ROLE 'app_reader', 'log_viewer' TO 'alice'@'%' - 若必须用
ALL,应配合activate_all_roles_on_login = ON全局设置,否则登录后仍不生效 -
FLUSH PRIVILEGES对角色权限无效,仅影响直接授予用户的权限;角色权限变更后,新连接自动生效,旧会话需手动SET ROLE - 连接池场景下(如 HikariCP),需配置
connection-init-sql="SET DEFAULT ROLE 'app_reader'",否则首次查询仍无权限
CURRENT_ROLE() 返回 NULL 就说明角色没激活,别信 SHOW GRANTS
SHOW GRANTS FOR 'alice'@'%' 只显示 GRANT 'app_reader' TO 这一行,完全不展开角色内含的权限——这是设计行为,不是 bug。靠它判断权限是否生效,100% 误判。
- 验证唯一可靠方式:
SELECT CURRENT_ROLE();登录后执行,返回非NULL值才算激活成功 - 如果返回
NULL,90% 是漏了SET DEFAULT ROLE,剩下 10% 是activate_all_roles_on_login未开启或客户端版本太低(mysql --version必须 ≥ 8.0.11) - 角色权限变更后,
CURRENT_ROLE()不会自动刷新,必须重新SET ROLE或新建连接 - 系统表
mysql.role_edges记录角色分配关系,但普通账号无权访问,只有root或有SELECT ON mysql.*的账号能查
真正容易被忽略的点在于:角色权限变更对已存在的活跃会话完全不生效,哪怕你刚 GRANT SELECT ON new_table TO 'app_reader',老连接仍然查不了这张表——必须让应用重建连接,或者手动在会话里执行 SET ROLE。


















