awr报告中大量空闲等待事件(如sql*net message from client)并非性能问题,而是数据库空闲状态的正常表现,本质是会话等待外部触发,不消耗cpu、不阻塞业务,但易误导dba误判热点;需通过wait_class='idle'精准识别并过滤,重点关注application、concurrency等非空闲类真实瓶颈。
awr报告里出现大量空闲等待事件,通常不是问题,而是数据库“没活干”的正常表现。 它们本身不消耗cpu、不阻塞业务,也不代表性能瓶颈——但容易让人误判为异常,尤其当它们在top 5里排名靠前时。
空闲等待事件是什么
空闲等待(Idle Wait)是Oracle主动挂起会话、等待外部触发的状态,比如等客户端发来下一条SQL、等定时器到期、等后台进程完成轮询。这类事件的WAIT_CLASS值固定为 Idle,在v$event_name中可查到共94种(Oracle 11g),常见如:
-
SQL*Net message from client:会话已返回结果,正安静等着客户端再发请求 -
PL/SQL lock timer:DBMS_LOCK.SLEEP之类调用后的休眠等待 -
rdbms ipc message:后台进程(如PMON、SMON)在无事可做时的内部等待 -
dispatcher timer、slave wait:共享服务器模式或并行查询空闲时的守候状态
它们本质是“休眠信号”,不是资源争抢,也不计入DB Time计算。
为什么它们会在AWR里占比高
AWR默认按“等待时间总和”排序Top 5事件,而空闲等待单次可能持续几秒甚至几分钟(比如应用端长连接空闲),累积时间很容易碾压那些毫秒级的非空闲等待(如db file sequential read)。几个典型场景:
- 应用使用连接池且连接长期复用,但SQL执行频次低 →
SQL*Net message from client时间暴涨 - 数据库负载轻,后台进程大部分时间在轮询 →
rdbms ipc message占比突升 - 有大量JOB或调度任务处于sleep状态 →
PL/SQL lock timer累计时间显著 - 启用了Shared Server但实际并发很低 →
dispatcher timer持续计时
注意:TIMED_STATISTICS = FALSE时,AWR改按“等待次数”排序,空闲事件反而不易上榜——但这会让真正关键的I/O或锁等待被掩盖,所以生产环境必须保持TRUE。
怎么快速区分空闲 vs 非空闲等待
别只看事件名,直接查WAIT_CLASS字段最可靠:
SELECT event, wait_class, total_waits, time_waited FROM dba_hist_system_event WHERE snap_id IN (SELECT MAX(snap_id) FROM dba_hist_snapshot) AND wait_class = 'Idle';
或者在AWR报告中翻到“Wait Classes by Total Wait Time”部分,Idle类单独列出,且明确标注“not included in DB Time”。如果该类占比超过70%,基本可确认系统当前负载极低。
真正要盯的是Application、Concurrency、User I/O、Commit这些非空闲类里的事件——它们才对应真实瓶颈。
什么情况下空闲等待真值得警惕
绝大多数时候不用管,但以下两种情况需人工核对:
-
SQL*Net break/reset to client或SQL*Net more data to client突增 → 可能是网络中断、客户端异常断连、或应用未正确关闭游标 - 本应高负载的时段(如交易高峰),
Idle类仍占绝对主导,且DB CPU持续低于10% → 要检查应用是否根本没连上来,或中间件配置错误(如连接串写错端口、服务名)
空闲等待本身不会拖慢数据库,但它们像一面镜子——照出的是应用行为、连接模型或监控误读,而不是Oracle内部出了故障。











