直接 truncate sys.aud$ 会失败,因为 Oracle 对该数据字典核心表施加隐式保护,即使 SYS 用户也无法直接 DDL 操作,且 truncate 不触发 DBMS_AUDIT_MGMT 清理逻辑,破坏审计时间戳一致性。
直接 truncate sys.aud$ 会失败,为什么?
在生产环境里,truncate table sys.aud$ 大概率报错 ora-00942: table or view does not exist 或 ora-01031: insufficient privileges。这不是权限不够,而是 oracle 对 sys.aud$ 施加了隐式保护:该表属于数据字典核心对象,即使以 sys 登录,也不能直接 ddl 操作(除非关闭审计且重启后临时启用)。更关键的是,truncate 不触发 dbms_audit_mgmt 的清理逻辑,可能破坏审计时间戳一致性,导致后续自动清理失效。
必须用 DBMS_AUDIT_MGMT.clean_audit_trail 清理
Oracle 11gR2 起强制要求通过官方包管理审计数据,否则无法保证归档时间戳和清理边界正确。手动 delete 也行,但风险更高——它不更新内部状态视图 dba_audit_mgmt_last_arch_ts,下次 clean 会重复清理或跳过。
-
BEGIN sys.DBMS_AUDIT_MGMT.set_last_archive_timestamp( audit_trail_type => sys.DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, last_archive_time => SYSTIMESTAMP - 7); END;—— 这步必须先跑,告诉 Oracle “7 天前的数据可删” -
BEGIN sys.DBMS_AUDIT_MGMT.clean_audit_trail( audit_trail_type => sys.DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, use_last_arch_timestamp => TRUE); END;—— 执行清理,注意use_last_arch_timestamp => TRUE必须显式指定,否则忽略上一步设置 - 清理后立即查
select count(*) from sys.aud$,数量下降但表段大小不变——这是正常现象,数据块标记为“可重用”,但未释放
清理后空间不回收?要 shrink + move
执行完 clean_audit_trail 后,sys.aud$ 占用的磁盘空间不会自动返还给表空间。因为 Oracle 只删除行记录,不收缩段。你得手动回收:
- 先确认当前表空间:
SELECT tablespace_name FROM dba_tables WHERE table_name = 'AUD$' AND owner = 'SYS' - 如果还在
SYSTEM表空间,强烈建议先迁出(见下一点),再执行:ALTER TABLE sys.aud$ SHRINK SPACE CASCADE—— 注意必须开启行移动:ALTER TABLE sys.aud$ ENABLE ROW MOVEMENT - 若已迁到专用表空间(如
AUDIT_TBS),可考虑ALTER TABLESPACE AUDIT_TBS COALESCE整合空闲区
别忘了 audit_trail=NONE 是治本方案
所有清理都是临时止血。Oracle 11g 默认 audit_trail=DB,只要开着,sys.aud$ 就会持续膨胀。生产环境若无合规审计要求,应关掉:
-
ALTER SYSTEM SET audit_trail=NONE SCOPE=SPFILE;—— 注意是SPFILE,不是BOTH,否则重启后恢复 - 必须重启生效:
SHUTDOWN IMMEDIATE; STARTUP; - 重启后验证:
SHOW PARAMETER audit_trail输出应为NONE;再查dba_audit_trail应为空 - 关掉之后,旧数据仍存在,但新操作不再写入 —— 此时再清理一次即可一劳永逸
真正麻烦的不是清理动作本身,而是清理后没关审计、没迁表空间、也没 shrink space,三者缺一,几周后又满。


















