SYSTEM表空间不可脱机、只读、重命名或删除,因其存储数据字典等核心对象;AUD$审计表长期未清理是其爆满主因,应通过DBMS_AUDIT_MGMT迁移或清理而非TRUNCATE。
SYSTEM表空间被设计为只读保护级别
oracle把system表空间当作数据库的“操作系统内核”,里面存的是sys用户下的数据字典表(如dba_tables、obj$)、内置pl/sql包(standard、dbms_output)、系统回滚段和ddl元信息。这些内容必须始终可用且一致,因此oracle在底层做了硬性限制:system不能offline、不能read only、不能重命名、也不能删除——连alter tablespace system ...这类语句都会直接报错,比如ora-01541或ora-01643。
非SYS用户根本无法获得写配额
即使你给用户授予了CREATE TABLE权限,甚至UNLIMITED TABLESPACE,只要对象试图落到SYSTEM表空间,就会触发ORA-01950: no privileges on tablespace 'SYSTEM'。原因很简单:Oracle不允许对SYSTEM表空间执行ALTER USER ... QUOTA,任何尝试都会静默失败或报ORA-02181。查一下配额就知道:SELECT tablespace_name, bytes FROM dba_ts_quotas WHERE username = 'YOUR_USER',结果里压根不会出现SYSTEM这一行。
AUD$审计表暴涨是SYSTEM爆满最常见原因
Oracle 11g起默认开启AUDIT_TRAIL=DB,所有审计记录都往SYS.AUD$里写,而这个表默认就建在SYSTEM表空间。一旦业务量上来、又没定期清理,AUD$轻松占掉几个GB,直接把SYSTEM撑到99%+,引发ORA-01653(无法扩展段)、ORA-00604(递归SQL出错),甚至导致新会话连不上库。
- 查大对象:
SELECT segment_name, bytes/1024/1024 MB FROM dba_segments WHERE tablespace_name='SYSTEM' ORDER BY bytes DESC - 清空审计表(需SYS权限):
TRUNCATE TABLE SYS.AUD$ - 更治本的做法:
EXEC DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, audit_trail_location_value => 'SYSAUX'),把AUD$迁走
性能开销翻倍,且无法通过参数优化彻底解决
实测表明,在SYSTEM表空间建用户表,CPU消耗和执行时间平均是普通表空间的2倍。虽然调_db_always_check_system_ts=FALSE能缓解,但这属于未公开内部参数,不稳定、不支持、不建议生产环境用。真正靠谱的做法,是让所有业务对象远离SYSTEM——改用户默认表空间:ALTER USER your_user DEFAULT TABLESPACE users,再配好配额:ALTER USER your_user QUOTA UNLIMITED ON users。
别指望靠扩容或加数据文件“救活”SYSTEM——那只是给定时炸弹多拧半圈螺丝。真正危险的不是空间满了,而是有人试图在SYSTEM里建索引、分区表、LOB字段,或者把历史归档数据塞进去。这些操作本身就会破坏数据字典一致性校验逻辑,问题往往在半夜三点才爆发。











