如何在 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