查MySQL表授权需直接查询mysql.tables_priv表,因无现成视图;Oracle需递归联查DBA_TAB_PRIVS、DBA_ROLE_PRIVS等;GBase 8s查sysauth/sysroleauth,PostgreSQL用has_table_privilege()函数结合系统表;云平台权限须用API或UI,不可SQL查询。
查 MySQL 表被谁授权:直接读 mysql.tables_priv
mysql 不提供“某张表有哪些用户有权限”的现成视图,但权限信息就存在系统库的 tables_priv 表里,这是最直接、最可靠的逆向溯源方式。
常见错误是只查 SHOW GRANTS FOR 'user'@'host'——这只能正向看用户,无法反向锁定表;或者误以为 information_schema.role_table_grants 有数据(它在 MySQL 8.0+ 才有且默认为空,不存实际授权记录)。
- 必须先用 root 或具备
SELECT权限的账号登录,否则查不到mysql库内容 - 注意字段大小写敏感:
db和table_name是小写存储,查询时要严格匹配(比如数据库名mydb不能写成MYDB) - 示例语句:
SELECT User, Host, Table_name, Column_priv, Table_priv FROM mysql.tables_priv WHERE db = 'mydb' AND table_name = 'orders';
-
Table_priv是逗号分隔字符串(如Select,Insert),不是布尔值;Column_priv同理,仅当列级授权存在时非空
Oracle 中反查表权限归属:绕不开 DBA_TAB_PRIVS + 角色展开
Oracle 没有“某表→所有授予权限用户”的单表视图,因为权限可能来自角色间接继承。只查 DBA_TAB_PRIVS 只能得到直接授权,漏掉 90% 的真实使用场景。
典型坑是 DBA 忘记连查角色路径:比如用户 APP_USER 没被直接授 SELECT 权限,但属于角色 READER_ROLE,而该角色被授了权限——这种链路必须手动展开。
- 基础查询(仅直接授权):
SELECT grantee, privilege, grantable FROM DBA_TAB_PRIVS WHERE owner = 'SCHEMA_NAME' AND table_name = 'EMPLOYEES';
- 要覆盖角色路径,得递归查
DBA_ROLE_PRIVS和ROLE_TAB_PRIVS,组合三层联查(用户→角色→表权限) - 如果目标用户是当前会话用户,可用
SESSION_ROLES缩小范围,避免全库扫描 - 注意:
DBA_*视图需 DBA 权限;普通用户只能用USER_TAB_PRIVS(只返回自己拥有的权限,无法逆向)
GBase 8s 和 PostgreSQL 的差异点:一个靠系统表,一个靠函数
GBase 8s 和 PostgreSQL 都不依赖“权限视图聚合”,而是把授权事实落在具体系统对象上,但实现逻辑完全不同。
GBase 8s 的表级权限分散在 sysauth(用户-对象权限映射)和 sysroleauth(角色-对象权限映射)两张表,且权限类型用数字编码(比如 1=select,2=insert),容易误读。
- 查 GBase 8s 表权限示例:
SELECT u.username, a.authid, a.tabname, a.privileges FROM sysauth a JOIN sysusers u ON a.grantee = u.userid WHERE a.tabname = 't1' AND a.owner = 'test';
- PostgreSQL 更统一:用内置函数
has_table_privilege()做判断,但逆向查需结合pg_class、pg_namespace和pg_authid手动关联,例如:SELECT r.rolname, c.relname, c.relkind FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace JOIN pg_authid r ON has_table_privilege(r.oid, c.oid, 'SELECT') WHERE c.relname = 'orders' AND n.nspname = 'public';
- PostgreSQL 中
pg_tables不含权限信息,别白费劲去查它
云平台(DMS/DataWorks)权限逆查:别碰 SQL,用控制台 API
阿里云 DMS、DataWorks 等平台的库表权限不是数据库原生权限,而是平台层 RBAC 控制,SQL 查不到。试图在 DMS 的 SQL 窗口里执行 SELECT * FROM mysql.tables_priv 会报错或返回空——因为底层根本没走 MySQL 实例的系统库。
这类环境必须走平台提供的权限接口或 UI 路径,否则永远查不到真实授权关系。
- DMS 用 OpenAPI:
ListUserPermissions接口,必填TenantId和UserId(不是阿里云 UID),支持按DatabaseName和SearchKey过滤 - DataWorks 在数据源详情页点“权限管理”→“表权限”选项卡,显示的就是当前用户可见的所有表(UI 已聚合角色+显式授权)
- 注意:
ListUserPermissions返回的是平台视角的权限,和数据库实例里实际生效的 GRANT 语句可能不一致(比如平台授权后未同步执行 GRANT)
权限逆向溯源真正的复杂点不在语法,而在权限模型本身:数据库原生权限、角色继承、平台抽象层、跨实例同步延迟——四层嵌套下,任何一个环节断开,查出来的结果就是错的。动手前先确认你查的是哪一层。

















