如何在Oracle中识别被阻止和被阻止的会话?

问题:

您想确定数据库中的阻塞会话和阻塞会话。

当我们在Oracle数据库中看到排队等待事件时,很可能有某些事情会锁定或阻止某些会话执行其SQL语句。当会话等待“入队”等待事件时,该会话正在等待其他会话持有的锁。我们可以发出以下命令来查看有关ORacle中被阻止和被阻止会话的信息。

示例

SELECT DECODE(request,0,'Holder: ','Waiter: ') || sid sess,
  id1,
  id2,
  lmode,
  request,
  type
FROM v$lock
WHERE (id1, id2, type) IN
  (SELECT id1, id2, type FROM v$lock WHERE request > 0
  )
ORDER BY id1,
  request;

V $LOCK视图显示实例中是否有任何阻塞锁。如果有阻止锁,它还会显示阻止会话和被阻止会话。

如果所有阻塞会话都想使用被阻塞的同一对象,则阻塞会话可以同时阻塞多个会话。

您可以使用下面的SQL来获取信息。

示例

select sid,type,lmode,request,ctime,block from v$lock;

输出结果

   SID           TY           LMODE             REQUEST       CTIME        BLOCK
--------------     --------     -----------    -----------   --------     -------    
       140           TX              4             6          11655          0
        38           TM              3             0            826          0
        38           TX              6             0            826          1

要监视的关键列是BLOCK列,其阻塞会话的值为1。在我们的示例中,会话38是阻止会话,因为它在BLOCK列下显示值1。SID为38的阻塞会话还在LMODE列下显示了一个锁定模式6,这表示它正在以独占模式持有此锁定。因此,会话140挂在同一谐振子上,无法执行其更新操作。被阻止的会话在BLOCK列中显示值为0。

如果要查找等待类以及阻塞会话阻塞了其他对象多长时间,我们可以通过查询V $SESSION视图来实现。

示例

SELECT blocking_session,
  sid,
  wait_class,
  seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL
ORDER BY blocking_session;

输出结果

BLOCKING_SESSION        SID           WAIT_CLASS        SECONDS_IN_WAIT
-----------------    --------       -------------    ------------------- 
       38                140          Application                  1237