oracle 19c无法通过单一开关禁查他人sql历史,必须通过审计关闭、权限收窄(如撤销select any dictionary)、会话视图访问控制三重手段实现隔离,因v$视图默认按用户过滤且审计视图是唯一持久化源头。
oracle 19c 本身不提供类似 mysql 的 process 权限隔离机制,也没有内置开关能直接禁止用户查他人 sql 历史——关键在于:**你根本不能靠“禁用某个视图”来实现,必须依赖审计关闭 + 权限收窄 + 会话隔离三重控制。**
为什么 DBA_AUDIT_TRAIL 和 UNIFIED_AUDIT_TRAIL 不是“查看入口”,而是“泄露源头”
很多人误以为查 DBA_AUDIT_TRAIL 是为了监控,其实它本身就是执行历史的唯一持久化载体。一旦开启审计(比如 AUDIT EXECUTE ON my_proc),所有执行者都会被记录,且任何有 SELECT ANY DICTIONARY 权限的用户都能查到完整记录,包括用户名、时间、SQL 文本。
- 没开审计时,
DBA_AUDIT_TRAIL是空的,但用户仍可能通过v$sql或v$session碰撞式猜测近期调用者(虽不可靠,但存在风险) - 开了审计却没收紧权限,等于把执行日志主动暴露给普通账号——
GRANT SELECT ON DBA_AUDIT_TRAIL TO app_user这种操作必须杜绝 -
UNIFIED_AUDIT_TRAIL同理,且默认只有UNIVERSAL或ADMINISTRATOR角色可查;普通用户即使被授SELECT_CATALOG_ROLE,也不应额外赋该视图权限
如何让普通用户只能看到自己的会话和 SQL
Oracle 没有全局“隐藏他人 SQL”的开关,但可通过权限与视图访问控制达成等效效果:
- 收回
SELECT ANY DICTIONARY权限:这是最关键的一步。该权限允许用户直接查v$session、v$sql、v$process等动态性能视图,而这些视图默认不按用户过滤 - 只授予
SELECT_CATALOG_ROLE(如有必要):它提供有限字典访问,但不包含v$系列;注意该角色不含v$sql查询权 - 禁用
CREATE SESSION以外的高危权限:如ALTER SYSTEM、ADMINISTER DATABASE TRIGGER,防止绕过限制创建跟踪会话的触发器 - 确认用户无法执行
SELECT * FROM v$session—— 应报错ORA-00942: table or view does not exist,而非返回空结果
别碰 v$sql 和 v$session 的“临时排查”陷阱
即使权限已收紧,仍有开发者试图用 v$sql 匹配过程名来反推调用者,这在生产环境极危险:
-
v$sql.sql_text可能被截断(默认 1000 字符),含绑定变量(如:b1),大小写不一致,或带换行/空格,导致LIKE '%MY_PROC%'失效或误匹配 -
v$session中的sql_id字段只反映当前正在执行的语句,历史执行无记录;且username字段对非自身会话返回NULL(权限隔离行为) - 依赖
last_active_time过滤(如SYSDATE - 1/24)并不可靠:共享池老化、SQL 被刷出、或启用 RESULT_CACHE 都会导致记录丢失 - 真正需要追溯执行者时,唯一可信路径是提前启用统一审计并限制审计视图访问,而不是事后从内存视图拼凑
最易被忽略的一点:Oracle 不像 MySQL 那样用单一权限控制进程可见性,它的“隔离”是分层的——权限收窄防读取,审计配置管记录,而 v$ 视图本身的访问控制逻辑(如仅返回本用户会话)才是底层防线。漏掉任意一层,都可能让“禁止查看”变成形同虚设。











