SHOW GRANTS FOR 'user'@'host' 仅显示用户显式权限,不包含角色继承、未激活角色、列级权限及部分库表权限;需结合 mysql.role_edges、INFORMATION_SCHEMA 视图等多源查询才能获取完整权限视图。

不能只靠 SHOW GRANTS FOR 'user'@'host' —— 它漏掉角色继承、未激活状态、列级权限,甚至可能查不到库/表级权限。
查指定用户显式授予的权限(基础但不完整)
执行 SHOW GRANTS FOR 'alice'@'%' 只返回该用户在 mysql.user、mysql.db、mysql.tables_priv 等表中被直接授予的权限语句。但它有硬伤:
- 不显示任何通过角色间接获得的权限(哪怕已
SET ROLE激活) - 如果用户绑了角色但没设默认角色,或当前会话未激活,这条命令仍只显示空壳
-
mysql.tables_priv.Table_name是 base64 编码值,SHOW GRANTS会自动解码并美化输出,但你无法从结果反推原始表名是否含特殊字符 - 低于 MySQL 8.0.19 时,列级权限根本不会出现在任何
SHOW GRANTS输出里
查角色绑定关系与叠加效果(必须做)
用户权限常来自角色,而角色可嵌套。关键表是 mysql.role_edges,它统一记录所有“授出→接收”关系:
- 查
'alice'@'%'直接绑定的角色:SELECT FROM_USER, FROM_HOST FROM mysql.role_edges WHERE TO_USER = 'alice' AND TO_HOST = '%'; - 查某个角色(如
'app_writer')是否被其他角色包含:SELECT * FROM mysql.role_edges WHERE FROM_USER = 'app_writer'; - 要看到叠加后的实际权限,必须用
USING显式指定角色:SHOW GRANTS FOR 'alice'@'%' USING 'app_writer', 'readonly_analyst'; - 若
USING后的角色名不存在,或用户根本没被GRANT过该角色,会报错ER_ROLE_NOT_GRANTED
确认角色是否在当前会话生效(容易被忽略)
绑定 ≠ 生效。即使查到用户绑了三个角色,当前连接也可能一个都没激活:
- 查当前会话已激活的角色:
SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES; - 查某用户被授予的所有角色(含未激活):
SELECT ROLE_NAME, IS_GRANTABLE FROM INFORMATION_SCHEMA.ADMINISTRABLE_ROLE_AUTHORITIES WHERE GRANTEE = '''alice'''@'''%''';(注意单引号需转义) - 如果
APPLICABLE_ROLES为空,但你知道用户绑了角色,大概率是漏了SET ROLE 'xxx';或没设默认角色(ALTER USER 'alice'@'%' DEFAULT ROLE 'app_writer';) -
SHOW GRANTS FOR ... USING不检查激活状态,它只做静态映射——哪怕你没SET ROLE,也能查出理论权限
补全列级权限和跨层级汇总(生产环境绕不开)
MySQL 8.0.19+ 才把列级权限存进系统视图,且 SHOW GRANTS FOR ROLE 和 USING 都不显示它们:
- 先确认版本:
SELECT VERSION();,低于 8.0.19 则跳过列级部分 - 查角色对某列的权限:
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, PRIVILEGE_TYPE FROM INFORMATION_SCHEMA.ROLE_COLUMN_GRANTS WHERE ROLE_NAME = 'app_writer'; - 真正拼出“全部权限”的最小可行查询,需手动联查:
mysql.user(全局)、mysql.db(库级)、mysql.tables_priv(表级)、mysql.role_edges(角色绑定)、INFORMATION_SCHEMA.ROLE_TABLE_GRANTS(角色拥有的库/表权限) - 普通用户默认无权查
mysql.*系统表,这类汇总必须由 root 或具备SELECT权限的管理员执行
真实有效权限 = 当前会话激活的角色 + 这些角色所带的全部库/表/列权限 + 用户自身被直接授予的权限。其中“激活状态”和“列级权限”最容易被跳过,一查就漏。











