使用 gv$session 判断查询是否挂起

9
我在Oracle中运行了一个查询,可能会挂起。现在已经运行了大约10个小时,但基于我正在加载的数据量,这可能不是不合理的。
我在gv $ session中查看会话,并想知道是否有一种方法将该信息翻译为实际上是否存在任何活动,或者查询是否因等待锁定或其他挂起而挂起。
我已经阅读了此视图的文档。这里提供链接。主要是想从那些在Oracle中调试此类问题方面具有经验的人那里获得提示。
谢谢!

1
你能在v$session_longops中找到一个条目来检查它是否正在进行吗?或者,可以查看此链接以了解如何查看会话是否被阻塞:http://www.orafaq.com/node/854 - Ollie
谢谢,我可以结合gv$sqlarea查看哪些语句正在耗费我的时间! - Paul
3个回答

11

gv$session中的event列告诉你当前会话正在等待的等待事件。如果您的会话正在等待由另一个会话持有的某种类型的锁,则event将告诉您这一点(例如,如果您正在等待在另一个会话持有的行上锁定,它将是"enq: TX - row lock contention"),而blocking_instanceblocking_session将填充锁的持有者的实例和会话ID。还可以查看seconds_in_wait(如果wait_time=0)以确定会话在当前等待事件中花费了多少秒。这至少可以告诉您是否当前会话“卡住”了,但它并不告诉您查询是否真的会完成--如果存在错误的计划,完全可能您遇到了"好的"等待事件,例如等待磁盘I/O,表明会话正在做某些事情,但查询实际上永远无法完成。


2
使用select 'ALTER SYSTEM KILL SESSION '''||sid||','||"SERIAL#"||''';', event from gv$session where machine = 'your machine'语句能够方便地生成命令来结束会话。只需复制并粘贴第一列即可。 - JDPeckham

7

根据进一步的研究和Ollie的评论,我提出了以下有助于调试问题的查询:

select s.sid, 
       s.username,
       s.machine,
       s.osuser, 
       cpu_time,
       (elapsed_time/1000000)/60 as minutes,
       sql_text
from gv$sqlarea a, gv$session s
where s.sql_id = a.sql_id
and s.machine like '####';


select lo.*, 
       a.sql_text
from gv$sqlarea a, gv$session_longops lo
where lo.sql_id = a.sql_id
and lo.sid = ####
order by lo.start_time;

1
不检查这些视图中的确切列,是否通过SQL_ID将gv$sqlarea链接到gv$session_longops更好?我现在不在电脑前,所以无法检查 :-( - Ollie

0

这将有助于检查当前运行的会话

select a.SID, a.SERIAL#, c.OBJECT_NAME 
from v$session a, v$locked_object b, user_objects c
where a.SID=b.SESSION_ID and b.OBJECT_ID=c.OBJECT_ID

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接