ASH中session_state全为WAITING属正常现象,因采样仅捕获非空闲等待且CPU执行窗口短易漏采,需结合event、blocking_session、LAST_CALL_ET等字段及DB CPU占比等指标综合判断真/假挂起。
ASH里session_state全是WAITING,不代表真卡死
oracle 12c的v$active_session_history中大量session_state = 'waiting'是正常现象,不等于数据库挂起或会话僵死。ash只记录非空闲等待状态的采样点,而绝大多数业务会话生命周期里90%以上时间都处于某种等待中——比如sql*net message from client(等应用发sql)、db file sequential read(等单块i/o)、enq: tx - row lock contention(等行锁)。
关键判断依据不是session_state本身,而是event列的具体等待事件类型和持续时间:
-
WAITING+SQL*Net message from client:应用端没发新请求,连接空闲,属正常 -
WAITING+enq: TX - row lock contention且blocking_session非空:真有阻塞,需查持锁会话 -
WAITING+log file sync且平均等待时间 > 10ms:可能IO写日志慢,不是会话问题而是存储问题
为什么看不到ON CPU或RUNNING状态的采样
ASH默认每秒采样一次,但ON CPU状态(即会话正在CPU上执行)只有在采样瞬间恰好落在CPU执行窗口内才会被捕获。实际中,短SQL、PL/SQL逻辑块、硬解析等CPU密集动作往往远小于1秒,极易漏采。所以你看到的session_state几乎全是WAITING,不是数据丢了,是采样粒度天然偏重等待侧。
想确认是否真有CPU瓶颈,得看其他指标:
- 查
V$SYS_TIME_MODEL里的DB CPU累计值,对比DB Time占比是否长期 >70% - 用
top -Hp <pid></pid>直接看oracle后台进程的CPU占用率 - AWR报告中“Top 5 Timed Events”里若
DB CPU排前三,才说明CPU真成瓶颈
如何区分真挂起和假挂起
真挂起指会话无法推进、无任何响应、且阻塞链持续存在;假挂起则是应用层行为(如长事务未提交、客户端休眠、网络中断后连接未释放),数据库内部其实一切正常。
快速验证方法:
- 查
V$SESSION中该会话的LAST_CALL_ET:>3600秒且STATUS = 'ACTIVE',大概率是应用没做超时控制 - 连查
blocking_session和final_blocking_session:若两者都为空,基本排除锁阻塞 - 看
SQL_ID是否为NULL:若为空,说明当前没在执行SQL,可能是PL/SQL循环、DBMS_LOCK.SLEEP或空连接 - 结合
PROGRAM和MACHINE字段:同一批python@host会话全卡在SQL*Net message from client,优先查应用端是否崩溃或网络断开
ASH采样失效时也会显示全是WAITING
如果V$ACTIVE_SESSION_HISTORY本身没数据,但你还强行查它,结果可能全是空或极少量记录,此时session_state看起来“异常一致”,其实是源头失真。
先确认ASH是否真在工作:
- 运行
SELECT COUNT(*) FROM v$active_session_history WHERE sample_time > SYSDATE - 1/1440;(查最近1分钟采样数),结果应为~60左右 - 检查
statistics_level参数:SELECT value FROM v$parameter WHERE name = 'statistics_level';,必须是TYPICAL或ALL,BASIC会禁用ASH - 别误用
DBA_HIST_ACTIVE_SESS_HISTORY查“实时”问题:它是AWR快照汇总表,延迟至少10分钟,不适合诊断刚发生的挂起
真正难定位的,是那些WAITING状态背后没有明确event、sql_id为空、program又显示为oracle@的会话——它们常由递归调用、硬解析失败或隐式DDL触发,得交叉查V$SESSION和V$SQL才能揪出根因。


















