审计日志存储位置取决于audit_trail参数值:db/true对应sys.aud$,unified对应audsys.aud$unified(须用dbms_audit_mgmt清理),os则存于audit_file_dest指定路径;unified模式下delete无效且报权限错。
查审计日志到底存在哪张表或哪类对象里
别一上来就删,先确认审计日志物理存储位置。统一审计(aud$unified)和传统审计(aud$)不能混用清理方式,否则会漏删甚至报错。
执行以下查询判断类型:
SELECT value FROM v$parameter WHERE name = 'audit_trail';
返回值常见三种:
-
DB或TRUE→ 走SYS.AUD$表(老式标准审计) -
UNIFIED→ 走AUDSYS.AUD$UNIFIED(必须用包清理) -
OS→ 日志在操作系统文件中,路径由audit_file_dest参数指定
如果返回 UNIFIED,后续所有 DELETE 操作都无效,必须调用 DBMS_AUDIT_MGMT;若返回 DB,则 AUD$ 是主战场,但注意它默认不启用行移动,SHRINK SPACE 会失败。
用AWR反向定位审计写入热点SQL
审计日志暴增往往不是均匀写入,而是某几条 SQL 在高频触发 INSERT INTO AUD$ 或 INSERT INTO AUD$UNIFIED。AWR 报告里的 Top SQL 模块能帮你揪出它们。
重点看这两个字段:
-
Executions极高但Elapsed Time Per Exec很低 → 短平快 DML,比如频繁INSERT/UPDATE触发细粒度审计(FGA) -
Parse Calls远大于Executions→ 硬解析多,说明应用没用绑定变量,每次执行都生成新审计记录
拿到可疑 SQL_ID 后,用下面语句查它是否被审计:
SELECT * FROM dba_audit_policies WHERE object_name IN (SELECT object_name FROM v$sql WHERE sql_id = 'xxx');
如果返回非空,说明这条 SQL 正在被策略捕获,且很可能没设条件过滤(比如缺 WHEN 子句),导致每行变更都记一条审计日志。
清理 AUD$UNIFIED 必须走 DBMS_AUDIT_MGMT,DELETE 无效
AUD$UNIFIED 是只读视图,底层数据存在内部压缩表中,直接 DELETE FROM AUDSYS.AUD$UNIFIED 会报 ORA-01031: insufficient privileges,哪怕你连的是 SYSDBA。
正确流程分三步:
- 先初始化清理作业(只需一次):
EXEC DBMS_AUDIT_MGMT.INIT_CLEANUP(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED, default_cleanup_interval => 24); - 设置清理时间窗口(比如只留最近7天):
EXEC DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED, last_archive_time => SYSTIMESTAMP - 7); - 真正执行清理:
EXEC DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED, cleanup_only => TRUE);
注意:第2步的 last_archive_time 必须早于实际最早记录时间,否则清理无效果。可用如下语句查最早时间:SELECT MIN(event_timestamp) FROM unified_audit_trail;
清理后空间不释放?WRH$_ 和 SMON_SCN_TIME 可能还在占坑
很多人清完审计日志发现 SYSAUX 没腾出多少空间,是因为 WRH$_ACTIVE_SESSION_HISTORY、SMON_SCN_TIME 或 LOGMNRC_* 段也在同步膨胀——尤其是开了 LogMiner 或逻辑复制的库,这些段会把审计事件的 SCN 映射关系长期缓存。
验证方法:
SELECT segment_name, bytes/1024/1024/1024 AS gb FROM dba_segments WHERE tablespace_name = 'SYSAUX' AND bytes > 1e9 ORDER BY bytes DESC;
如果看到 LOGMNRC_SEED$ 或 WRH$_SQL_PLAN 排前三,说明 AWR 快照本身也积压严重。此时需配合:
- 对单个大分区快速释放:
ALTER TABLE WRH$_ACTIVE_SESSION_HISTORY TRUNCATE PARTITION <partition_name> UPDATE GLOBAL INDEXES;</partition_name> - 收缩已删数据但未回收的空间:
ALTER TABLE SYS.WRH$_ACTIVE_SESSION_HISTORY SHRINK SPACE CASCADE;(需先ENABLE ROW MOVEMENT) - 检查 LogMiner 是否残留:
SELECT session_id, start_scn, end_scn FROM v$logmnr_session;,若有活跃会话,补上DBMS_LOGMNR.END_LOGMNR
最易被忽略的一点:drop_snapshot_range 只删元数据,不删物理数据;而 TRUNCATE PARTITION 才是真正腾空间的“快刀”。别信“清理完就完事”,得盯 dba_segments 输出确认 GB 数降下来才算落地。











