SYSTEM表空间溢出主因是审计表AUD$、统计信息历史(WRI$_OPTSTAT_*)及回收站残留,而非用户索引本身;其元数据(定义、依赖、权限等)强制存于SYSTEM,删索引不释放空间。
system 表空间溢出和索引数量没有直接因果关系——真正吃掉 system 空间的是索引的元数据(data dictionary entries)、审计信息、统计信息历史、以及未清理的回收站对象,而不是索引本身占的数据块。
为什么删了索引,SYSTEM 空间还不降?
Oracle 的 SYSTEM 表空间不存用户索引的数据段(那些在业务表空间里),但它强制存放所有索引的定义、列依赖、权限、审计策略、统计信息快照等字典信息。尤其当长期开启 AUDIT、频繁收集统计信息、或执行过大量 DROP INDEX 但没清回收站时,SYSTEM 里的 OBJ$、COL$、IAUX$、WRI$_OPTSTAT_* 表会持续膨胀。
- 查回收站是否塞满:
SELECT COUNT(*) FROM dba_recyclebin WHERE can_undrop = 'YES';大量残留说明DROP INDEX后没执行PURGE RECYCLEBIN - 看统计信息历史是否失控:
SELECT COUNT(*) FROM wri$_optstat_histhead_history;超百万行大概率是主因 - 确认审计是否开启:
SELECT value FROM v$parameter WHERE name = 'audit_trail';若为DB或XML,且没定期清理UNIFIED_AUDIT_TRAIL或AUD$,审计记录会撑爆 SYSTEM
快速释放 SYSTEM 空间的关键操作
别碰 SYSTEM 数据文件 resize——它不允许 shrink,强行 resize 可能损坏字典。优先走“逻辑清理”:
- 清空回收站:
PURGE RECYCLEBIN(注意:不可逆,确保真不需要闪回) - 清理过期统计信息:
EXEC DBMS_STATS.PURGE_STATS(SYSDATE - 30)(保留最近 30 天,按需调) - 停用非必要审计:
AUDIT NONE;,再删旧审计记录:DELETE FROM aud$ WHERE timestamp# < SYSDATE - 90,然后COMMIT - 收缩字典表(11g 支持):
ALTER TABLE sys.aud$ SHRINK SPACE COMPACT;、ALTER TABLE sys.wri$_optstat_histhead_history SHRINK SPACE COMPACT;
哪些操作反而会让 SYSTEM 更糟?
误判问题根源容易引发二次恶化:
- 执行
ALTER DATABASE DATAFILE '<system01.dbf>' RESIZE ...:SYSTEM 数据文件不支持在线 shrink,resize 只能增大,不能减小 - 手动
TRUNCATE字典表(如aud$):11g 不允许直接 truncate 系统基表,会报ORA-00942或破坏一致性 - 盲目重建索引:
ALTER INDEX ... REBUILD会在业务表空间产生新段,但索引定义仍写入 SYSTEM,且临时段可能额外占用 TEMP - 用
EXP/IMP导出导入 SYSTEM:极危险,可能丢失关键字典状态,导致实例无法启动
后续必须堵住的漏点
清理完只是止损,不改习惯一周就回弹:
- 禁用自动统计信息收集(若业务可控):
EXEC DBMS_AUTO_TASK_ADMIN.DISABLE(client_name => 'auto optimizer stats collection', operation => NULL, window_name => NULL) - 审计策略分级:只对关键表/用户审计,避免
AUDIT ALL;启用统一审计(12c+)前,11g 建议用NOAUDIT显式关闭非核心项 - 监控字典增长:
SELECT segment_name, bytes/1024/1024 MB FROM dba_segments WHERE tablespace_name = 'SYSTEM' ORDER BY 2 DESC,重点关注AUD$、WRI$_OPTSTAT*、SEG$
最常被忽略的是统计信息历史保留策略——默认永不清除,DBMS_STATS.PURGE_STATS 必须纳入运维脚本定时跑,否则三年后 WRI$_OPTSTAT_HISTHEAD_HISTORY 占满 SYSTEM 几乎必然发生。


















