我有一个在 Oracle 中运行的查询,它可能会或可能不会挂起。它现在已经运行了大约 10 个小时,但根据我正在加载的数据量,这可能不是不合理的。
我正在查看 gv$session 中的会话,想知道是否有办法翻译该信息以查看是否真的有任何活动正在进行,或者查询是否卡在等待锁定或以其他方式挂起。
我已经在此处阅读了此视图的文档。我主要是从任何有在 Oracle 中调试此类问题的经验的人那里寻找提示。
谢谢!
在gv$session
中,该event
列告诉您会话当前正在等待什么等待事件。如果您的会话正在等待另一个会话持有的某种锁,event
则会告诉您(例如,如果您排队等待锁定另一个会话持有的行,它将是“enq: TX - row lock contention”)并且将使用锁持有者的实例和会话 ID 填充blocking_instance
。blocking_session
您还可以查看seconds_in_wait
(如果wait_time=0
) 来确定会话在当前等待事件中花费了多少秒。这至少应该告诉您您的会话当前是否“卡住”,但它不会告诉您您的查询是否真的会完成——如果有一个糟糕的计划,那么您完全有可能得到“好”等待磁盘 I/O 等事件表明会话正在执行某些操作,但查询永远不会真正完成。
基于一些进一步的研究和 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;
这将有助于检查当前正在运行的会话
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