ORA-1688 错误通常并非 SYSAUX 物理空间耗尽,而是因 MMON 进程异常导致 WRH$ 表快照积压、分区膨胀及自动清理失效;需综合检查 v$bgprocess 中 MMON 状态、WRH$ 段占用、dba_hist_wr_control 保留策略及分区数量。
ORA-1688 错误出现时,SYSAUX 表空间真的满了吗?
看到 ora-1688: unable to extend table sys.wrh$<em></em> 这类报错,第一反应是 sysaux 满了——但实际常不是“物理空间耗尽”,而是表空间里有大量未清理的旧快照数据,且自动清理被阻塞。oracle awr 默认靠 mmon 进程每小时执行一次清理,但如果它卡住、挂起或被禁用,wrh$* 表就会持续膨胀,哪怕 sysaux 还剩 20% 空间也会报 ora-1688。
- 检查真实使用率别只看
dba_free_space,要查dba<em>segments</em>中WRH$相关段占了多少:SELECT segment_name, bytes/1024/1024 MB FROM dba_segments WHERE tablespace_name = 'SYSAUX' AND segment_name LIKE 'WRH$_%' ORDER BY bytes DESC FETCH FIRST 5 ROWS ONLY;
- 查
dba_hist_wr_control确认保留策略是否被意外设成极大值(如 10000 天),这会让清理逻辑直接失效 - 注意:
SYSAUX中SM/AWR组件占用超 70% 时,MMON清理动作大概率已滞后
MMON 进程没在跑?先确认它是否真挂了
MMON 是 AWR 快照采集与自动维护的核心后台进程,但它不显示在 v$session 里,也不能用 ps -ef | grep mmon 直接看到 Linux 进程名(它混在 ora<em>m000</em>* 类似名称中)。错误判断它“死了”会导致误操作。
- 查活跃状态最准的方式是:
SELECT name, state, recovery_target FROM v$managed_standby WHERE name = 'MMON';
——但这个视图其实不反映 MMON;正确做法是查v$bgprocess:SELECT * FROM v$bgprocess WHERE pname = 'MMON';
如果没返回行,或SPID为空,说明进程异常退出 - 常见诱因:数据库刚经历实例崩溃后重启,
MMON可能因内部 latch 冲突卡在初始化阶段,此时alter system flush shared_pool无用,必须等它自己恢复或重启实例 - 不要手动 kill
MMON进程(比如通过orakill),它没有安全重启机制,强行终止会导致后续快照生成永久失败
手动清理 WRH$_ 表前,必须绕过 DBMS_WORKLOAD_REPOSITORY 的隐式锁
想用 EXEC DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT<em>RANGE(...)</em> 删除旧快照?小心它会在内部对 WRH$ 表加 DML 锁,而如果已有长事务正在写入 AWR(比如另一个 MMON 子进程正往 WRH$_ACTIVE_SESSION_HISTORY 插数据),这个存储过程会无限等待,看起来像“卡住”。
- 先查有没有阻塞:
SELECT blocking_session, event, sql_id FROM v$session WHERE program LIKE '%MMON%' AND state = 'WAITING';
- 更稳妥的手动清理方式是分批 truncate(仅限归档模式+已备份的前提下):
ALTER TABLE WRH$_SQLTEXT TRUNCATE PARTITION BEFORE (TO_DATE('2023-01-01','YYYY-MM-DD')) UPDATE GLOBAL INDEXES;——注意必须带UPDATE GLOBAL INDEXES,否则全局索引失效,AWR 查询直接报错 - 切勿直接
DROP TABLE或DELETE FROM WRH$_:这些表受 Oracle 内部约束保护,硬删会破坏数据字典一致性
快照生成失败后,WRH$_ 分区增长失控的典型征兆
一旦 AWR 快照连续失败超过 3 小时,WRH$_ 表的分区策略(按时间范围切分)会开始“堆积”:新分区建不出来,老分区又清不掉,结果就是单个表里冒出几百个空分区,每个都占几 MB 数据字典开销,最终拖慢整个 SYSAUX 访问性能。
- 查分区数量:
SELECT table_name, COUNT(*) FROM dba_tab_partitions WHERE table_name LIKE 'WRH$_%' GROUP BY table_name ORDER BY 2 DESC;
若WRH$_ACTIVE_SESSION_HISTORY超过 200 个分区,基本可判定清理链路已断裂 - 分区元数据本身不占磁盘空间,但 Oracle 维护它们需要 CPU 和 library cache latch,高并发下会引发
library cache lock等间接等待 - 此时即使腾出 10 GB 空间,
MMON也不会自动恢复——必须先用DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS临时缩短保留期,逼它触发一次强制清理循环
这事最难的地方不在命令怎么敲,而在你得同时盯住三件事:MMON 进程状态、WRH$_ 分区元数据健康度、以及 SYSAUX 里那些看不见的索引和 LOB 段的实际碎片情况。漏掉任何一项,清理完一小时就复发。










