SYSTEM表空间增长主因是AUD$审计表堆积,需用DBMS_AUDIT_MGMT官方包清理并迁移至非SYSTEM表空间,同时检查DBA_SCHEDULER_JOB_LOG是否误驻SYSTEM并处理。
system表空间持续增长,90%以上是 aud$ 在撑,不是配置错、也不是sql写得烂,而是审计记录日积月累没管。
查清楚是不是 AUD$ 在占坑
别猜,直接看前几大的段:
-
SELECT owner, segment_name, bytes/1024/1024 MB FROM dba_segments WHERE tablespace_name = 'SYSTEM' ORDER BY bytes DESC—— 如果第一行就是AUD$(且OWNER是SYS),基本不用往下看了 - 再确认审计是否真开着:
SHOW PARAMETER audit_trail—— 返回DB或DB, EXTENDED就是它;返回NONE或FALSE可跳过清理AUD$这步 - 顺手看看有没有误建的用户对象:
SELECT owner, segment_name FROM dba_segments WHERE tablespace_name = 'SYSTEM' AND owner NOT IN ('SYS', 'SYSTEM')—— 如果有非系统用户出现在结果里,说明有人建表没指定表空间,得立刻改默认表空间并迁移对象
别 TRUNCATE TABLE aud$,用 DBMS_AUDIT_MGMT 清理
硬 truncate 会锁表、阻塞新审计写入,还可能触发 ORA-00600。Oracle 11gR2 起就该走官方路径:
- 先初始化(只做一次):
BEGIN DBMS_AUDIT_MGMT.INIT_CLEANUP(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD); END;—— 若报ORA-46262,说明没初始化,必须先跑这句 - 设保留窗口(比如只留 90 天):
EXEC DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, last_archive_time => SYSTIMESTAMP - 90) - 真正执行清理:
EXEC DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, cleanup_only => TRUE) - 清理完不等于空间回收 ——
AUD$表本身还在 SYSTEM 里,得手动挪走:ALTER TABLE aud$ MOVE TABLESPACE users,再ALTER TABLE aud$ SHRINK SPACE(确保启用了行移动)
检查 DBA_SCHEDULER_JOB_LOG 是否也在 SYSTEM 里膨胀
调度任务日志默认写进 SYSAUX,但某些老版本或自定义配置下,DBA_SCHEDULER_JOB_LOG 的基表或索引可能意外落在 SYSTEM。虽然少见,但一旦发生,增长速度不亚于 AUD$:
- 查位置:
SELECT owner, segment_name, tablespace_name FROM dba_segments WHERE segment_name IN ('JOB_LOG', 'SCHEDULER$_JOB_LOG') AND owner = 'SYS' - 如果
tablespace_name是SYSTEM,说明配置异常;应通过DBMS_SCHEDULER.PURGE_LOG清理历史日志,并用ALTER TABLE scheduler$_job_log MOVE TABLESPACE sysaux迁移(注意:需先禁用相关 job,且迁移后重建索引) - 长期方案:在创建 job 时显式指定
LOGGING OFF,或定期调用DBMS_SCHEDULER.PURGE_LOG(log_history => 30)(保留 30 天)
真正麻烦的从来不是“怎么清”,而是清完后没人关掉自动归档策略、没人调大 DBMS_AUDIT_MGMT 的清理窗口、也没人检查 audit_trail 是否又悄悄被设回 DB —— 这些细节漏掉一个,三个月后 SYSTEM 又会回到 95%。











