MySQL 8.0无内置命令生成角色继承关系图,需手动查询mysql.role_edges表并递归拼接;该表记录角色授予关系(FROM_USER为父角色,TO_USER为子角色),但不自动传递权限,且SHOW GRANTS USING不展开嵌套权限或校验激活状态。

MySQL 8.0 没有内置命令或视图能直接生成“继承关系图”,所谓“角色继承”本质是 mysql.role_edges 表中显式的父子指向,必须手动查表+拼接,不能一键出图。
查角色嵌套链:从 mysql.role_edges 提取父子关系
角色是否被授予另一个角色,只记录在 mysql.role_edges 中,字段含义固定:FROM_USER 是被授予的角色(父),TO_USER 是接收者(子)。该表支持角色嵌套(A→B→C),但不表示权限自动传递。
- 查某角色(如
app_writer)直接拥有的上游角色:SELECT FROM_USER, FROM_HOST FROM mysql.role_edges WHERE TO_USER = 'app_writer' AND TO_HOST = '%'; - 查某角色(如
base_role)被哪些角色授予(即它的下游):SELECT TO_USER, TO_HOST FROM mysql.role_edges WHERE FROM_USER = 'base_role' AND FROM_HOST = '%'; - 要展开完整链(比如 A→B→C→用户),得递归查询或写脚本多层 JOIN,MySQL 原生不支持递归 CTE 查角色树(8.0.14+ 才支持,且
role_edges不保证无环)
SHOW GRANTS USING 只显示静态授权,不反映嵌套生效状态
执行 SHOW GRANTS FOR 'alice'@'%' USING 'app_writer' 能看到 app_writer 自身的权限语句,但不会自动展开它所依赖的 app_reader 或 base_role 的权限——那些得单独再对每个上游角色执行一次 SHOW GRANTS FOR ... USING。
- 如果
app_writer有GRANT 'app_reader' TO 'app_writer',但app_reader后来被删了,SHOW GRANTS USING 'app_writer'仍成功返回,不会报错或提示失效 - 角色权限是否真起效,取决于会话是否激活(
SET ROLE)及用户是否被GRANT过该角色,SHOW GRANTS USING不校验这些运行时条件
用 INFORMATION_SCHEMA.APPLICABLE_ROLES 验证当前会话实际激活的角色
即使角色链存在,没激活就等于没权限。登录后查 INFORMATION_SCHEMA.APPLICABLE_ROLES 才知道哪些角色处于“可用但未激活”状态,而 CURRENT_ROLE() 只返回当前生效的那个。
- 查当前用户已激活的角色:
SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES WHERE IS_ASSIGNED = 'YES'; - 查某用户(如
'dev'@'10.%')所有被授予的角色(含未激活):SELECT ROLE_NAME FROM INFORMATION_SCHEMA.ADMINISTRABLE_ROLE_AUTHORIZATIONS WHERE GRANTEE = '''dev''@''10.%''';(注意引号转义) - 角色链里任意一环未被
SET ROLE或设为默认角色,整条链就断在那一层,下游权限不生效
真正难的是把 role_edges 的边、各角色自身的 SHOW GRANTS 结果、以及用户当前激活状态三者对齐——没有单条 SQL 能输出“谁通过哪条路径获得了什么权限”。你得先确认角色链存在,再逐层查权限,最后验证会话激活,漏一步就误判。


















