当数据库系统运行异常,通常我们会到v$session视图查看当前的event,这个event就是当前session的等待事件吗?
有可能不是。
现在模拟一个场景来证明一下以上的结论。
首先用户sichuan登陆数据库,取得自己的sid和spid,方便后续查看该会话的相关信息。
SQL> select s.sid,s.serial#,p.spid from v$session s, v$process p, (select * from v$mystat where rownum=1) ms where s.paddr=p.addr and s.sid=ms.sid;
SID SERIAL# SPID ---------- ---------- ------------------------ 393 35205 3081102 |
使用另外一个用户jiangsu来观察用户sichuan此时的状态,发现用户sichuan的状态是inactive,当前的event是SQL*Net message from client
SQL*Net message from client
The server process (foreground process) waits for a message from the client process to arrive.
该等待事件是一个空闲等待,表示oracle server进程在等待用户发出下一条指令

用户sichuan执行一个死循环命令,用来模拟消耗cpu资源
begin while true loop null; end loop; end; / |
用户jiangsu再查看sichuan的状态如下,唯一改变的是会话状态从inactive变成了active,但是event还是SQL*Net message from client。

用户sichuan事实上正在执行一个死循环脚本,这是非常消耗CPU的。但是从v$session视图中查看到的却是一个空闲的等待,那么到底是不是空闲的等待呢?如果确认了用户sichuan进程当前CPU的消耗,就可以证明:v$session视图里的event有可能不是当前会话的等待事件。
topas -p 3081102 |
输出结果如下

进程3081102(sichuan)确实消耗了很多cpu资源。也就是说v$session视图里的event有可能不是当前会话的等待事件。
这是为什么呢?
这里需要介绍v$session视图中的state字段

当且仅当v$session.state=waiting的时候,才表示该session正在等待这个event,也就是v$session.event的记录是当前会话的等待事件。否则代表该会话正在on cpu,此时,v$session.event记录的是该会话on cpu之前的最后一个等待事件。

从查询的结果来看,v$session.state=waited known time,并不是waiting,那么就说明这个进程正在on cpu,event=SQL*Net message from client是会话on cpu之前的最后一个等待。




