应重点查看AWR报告中Background Processes和Wait Events两部分,检查SMON的DB Time、CPU、物理读是否异常增长,以及是否存在buffer busy waits等争用信号;需用awrrpti.sql生成15分钟粒度报告并对比连续2–3份;确认死事务回滚需查V$FAST_START_TRANSACTIONS,状态为RECOVERING且进度停滞即表明卡住;不可通过FAST_START_PARALLEL_ROLLBACK关闭进行中的回滚,唯一中断方式是重启实例但风险高,稳妥做法是定位并清理源头事务;undo损坏导致ORA-00600[4194]须联系Oracle Support。
SMON 进程 CPU 或 I/O 飙高,AWR 里该看哪几张报告?
直接看 top 5 timed foreground events 和 instance activity stats 两个部分,别先翻 sql。smon 消耗高往往不是 sql 引起的,而是内部恢复任务在持续运行——比如死事务回滚(dead transaction rollback)卡住了。
重点检查:AWR 报告中 “Background Processes” 小节下的 SMON 行,对比前后快照的 DB Time、DB CPU、Physical Reads 是否异常增长;再查 “Wait Events” 里有没有大量 buffer busy waits 或 read by other session,这是 SMON 在争抢数据块的典型信号。
-
AWR默认每小时生成一次,如果 SMON 高负载只持续十几分钟,可能被平均掉——要主动用awrrpti.sql手动生成 15 分钟粒度的报告 - 别只看最新一份报告,至少对比连续 2–3 份,确认是突发还是持续现象
- 如果数据库启用了
in-memory,SMON还可能参与 IMCU 清理,此时需额外核对V$INMEMORY_AREA
怎么确认是不是死事务回滚卡住了?
死事务回滚一旦启动,SMON 会持续扫描 undo segment 头部的事务表(transaction table),尝试清理已提交但未清除的 ITL 条目。这个过程不记入 V$SESSION_LONGOPS,所以常规“查长操作”会漏掉。
真正有效的判断方式是查 V$FAST_START_TRANSACTIONS:
SELECT usn, state, undoblockstotal, undoblocksdone,
decode(undoblockstotal, 0, 0, round(undoblocksdone/undoblockstotal*100,2)) pct_done
FROM V$FAST_START_TRANSACTIONS;
只要结果非空,就说明有事务回滚正在进行;如果 state = 'RECOVERING' 且 pct_done 长时间不动(比如 10 分钟内变化
-
V$FAST_START_TRANSACTIONS只显示被fast_start_parallel_rollback触发的回滚,手动ROLLBACK不会出现这里 - 如果查不到记录,但 SMON 仍高负载,可能是 undo segment header 本身损坏,需检查 alert.log 中是否有
ORA-00600 [4194]或[4193] -
undoblocksdone偶尔倒退是正常现象(回滚中途遇到一致性读失败重试),但持续为 0 就危险
SMON 卡在 undo block 读取,undo_retention 和 undo_tablespace 怎么影响它?
SMON 回滚死事务时,必须从 undo 表空间读取原始的 undo record。如果 undo 数据已被覆盖(比如 undo_retention 设置过短,或 undo 表空间太小导致频繁 reuse),SMON 会反复尝试构造一致性读镜像,引发大量 db file sequential read 和 buffer busy waits。
关键参数实际影响如下:
-
undo_retention是软限制,不保证 undo 一定保留那么久;真起作用的是 undo 表空间是否AUTOEXTEND以及剩余空间是否充足 - 如果
UNDO_TABLESPACE使用的是FIXED SIZE(即未启用 autoextend),即使undo_retention设为 3600,空间满后也会立刻覆盖旧 undo - 检查
V$UNDOSTAT的MAXQUERYLEN和UNXPSTEALCNT:前者大于 0 说明有查询被拖长,后者持续 > 0 表示 undo 正在被强制复用
强行终止死事务回滚?ALTER SYSTEM SET FAST_START_PARALLEL_ROLLBACK 能关吗?
不能直接关。设置 FAST_START_PARALLEL_ROLLBACK = FALSE 只影响后续新触发的回滚,对已在进行的 V$FAST_START_TRANSACTIONS 任务完全无效。SMON 会继续跑完它。
唯一能中断的方式是重启实例(SHUTDOWN IMMEDIATE),但风险极高:重启后 SMON 会在下一次启动时重新扫描并再次触发回滚,问题大概率重现。
- 更稳妥的做法是先定位源头:查
V$TRANSACTION和V$SESSION关联,找到那个长时间未提交的会话(STATUS = 'ACTIVE'且USED_UREC > 100000) - 如果会话已断连但事务残留,可尝试
ALTER SYSTEM KILL SESSION '<sid>,<serial>' IMMEDIATE</serial></sid>,有时能促使其转入正常回滚流程 - Oracle 12c+ 可用
DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY清理疑似丢失的分布式事务条目,但必须严格按 MOS 文档步骤执行,否则破坏数据一致性
最麻烦的情况是 undo block 物理损坏,这时 SMON 会陷入无限重试循环,alert.log 里反复出现 ORA-00600 [4194]。这种必须联系 Oracle Support,自己无法安全修复。










