privilege analysis是oracle运行时权限捕获工具,仅记录用户会话中实际执行的需权限操作(如select、execute),不自动识别冗余权限,也不分析授权语句或代码逻辑,需人工比对dba_used_privs与原始授权清单才能判断未用权限。

Privilege Analysis 不能直接识别“冗余权限”,它只记录实际被使用的权限;是否冗余,得靠你人工比对使用记录和授予清单。
Privilege Analysis 是什么,不是什么
它是一个运行时捕获工具,启用后会默默记录用户在会话中「真正执行」了哪些需要权限的操作(比如 SELECT 某张表、EXECUTE 某个过程),但不会主动判断哪些权限“没用”或“多余”。它不分析授权语句本身,也不扫描代码逻辑——只看真实 SQL 执行路径上触发的权限检查点。
常见误解包括:
- 以为开启后就能自动生成“可回收权限列表”——实际只产出
DBA_USED_PRIVS这类视图里的原始调用记录 - 期待它能发现“被 GRANT 但从未调用”的系统权限——它确实能捕获到
CREATE SESSION这类行为,但前提是用户真连进来做了事;空连接、未执行任何语句的会话不会留下痕迹 - 认为它覆盖所有权限类型——它不捕获密码验证、PROFILE 限制、角色启用(
SET ROLE)等非 DML/DCL 执行链上的环节
怎么启用并捕获有效权限使用
必须用具有 EXP_FULL_DATABASE 或 ADVISOR 权限的用户(通常是 DBA)操作,且数据库需处于 OPEN 状态。关键步骤如下:
- 创建分析策略:
EXEC DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE('sales_capture', 'ROLE', 'SALES_ROLE');—— 这里指定捕获 SALES_ROLE 角色下的权限使用,也可用'USER'模式针对单个用户 - 启用策略:
EXEC DBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE('sales_capture'); - 让目标用户/角色在业务窗口期内正常操作(例如跑完一个报表周期、完成一次 ETL)
- 停用策略:
EXEC DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE('sales_capture'); - 生成分析结果:
EXEC DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULT('sales_capture');
完成后,查询 DBA_USED_PRIVS 可看到每条被实际调用的权限(含对象名、类型、被谁调用),而 DBA_UNUSED_PRIVS 则需手动对比原始授权清单才能得出——Oracle 不自动填充这个视图。
为什么查不到某些明显该有的权限调用
几个高频漏捕场景:
- 用户用的是角色(如
CONNECT),但角色内含的CREATE SESSION不会被单独记为“已用”,因为登录动作本身不走权限检查缓存路径;只有后续第一个 SQL 才开始记录 - 使用了动态 SQL(
EXECUTE IMMEDIATE)且拼接了对象名,若对象名是变量而非字面量,Privilege Analysis 可能无法解析出具体对象,只记为SELECT ANY TABLE这类泛权限 - 跨数据库链(DB Link)访问远端对象时,本地策略不捕获远端权限使用,只记录本地发起方是否用了
CREATE DATABASE LINK或SELECT ANY TABLE - PL/SQL 包体内硬编码的查询,若包以
DEFINER'S RIGHT执行,记录的是包属主的权限使用,不是调用者的
如何把捕获结果转化成可操作的权限瘦身方案
核心是两步比对:先拉出当前授予的全部权限,再减去 DBA_USED_PRIVS 中出现过的。示例流程:
- 导出角色 SALES_ROLE 的全部授权:
SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'SALES_ROLE';+SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'SALES_ROLE';+SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'SALES_ROLE'; - 查出该角色下用户实际用到的权限:
SELECT DISTINCT PRIVILEGE, OBJECT_NAME, OBJECT_TYPE FROM DBA_USED_PRIVS WHERE USED_ROLE = 'SALES_ROLE'; - 人工排除:比如
SELECT ANY DICTIONARY出现在DBA_USED_PRIVS里,但你确认只是运维脚本临时调用,业务系统不该有——那就不能删,得改脚本 - 注意列级权限:如果业务只查 EMP 表的
EMPNO和ENAME,但授予的是整表SELECT,Privilege Analysis 不会告诉你哪几列被读了,得结合审计或应用日志补全
真正容易被忽略的,是权限依赖的隐式链条:比如删掉某个 SELECT 权限后,一个视图失效,导致下游几十个报表报错——Privilege Analysis 不体现这种间接影响,必须结合数据血缘或依赖分析一起看。











