查找阻塞等待,锁等待源头


一、查看阻塞的源头
1.在60分钟内查看引起等待最多的SQL:

select ash.user_id,
u.username,
s.sql_text,
sum(ash.wait_time +
ash.time_waited) ttl_wait_time
from v$active_session_history ash,
v$sqlarea s,
dba_users u
where ash.sample_time between sysdate - 30/2880 and sysdate
and ash.sql_id = s.sql_id
and ash.user_id = u.user_id
group by ash.user_id,s.sql_text, u.username
order by ttl_wait_time;



2.在数据库hang的时间段内,有多少个session在等待'enq: TA - contention'
select event,count(*) from dba_hist_active_sess_history 
where event='enq: TA - contention' and instance_number=2
group by sample_time,event order by sample_time;


3.查看哪些会话在等待
select session_id,session_serial#,session_state,blocking_session_status,
blocking_session b_sess,BLOCKING_SESSION_SERIAL# b_ser,BLOCKING_INST_ID inst
from dba_hist_active_sess_history 
where event='enq: TA - contention' and instance_number=2 
order by sample_time;

4.查看哪些会话在阻塞另一个会话
select session_id,session_serial# serial,event,session_state,blocking_session_status state,
blocking_session b_sess,BLOCKING_SESSION_SERIAL# b_ser,blocking_inst_id inst    
from dba_hist_active_sess_history
where session_id=3666 and session_serial#=11235 and instance_number=2
order by sample_time;

5.通过blocking_session b_sess,BLOCKING_SESSION_SERIAL#作为条件,查看阻塞源头。


二、查看锁的源头
WITH LOCK_1 AS
 ( SELECT DISTINCT S.INST_ID, S.SID, S.BLOCKING_SESSION, S.LAST_CALL_ET
    FROM GV$SESSION S
   WHERE S.BLOCKING_SESSION IS NOT NULL
     and BLOCKING_SESSION_STATUS = 'VALID' )
SELECT BLOCKING_SESSION
  FROM LOCK_1
  WHERE BLOCKING_SESSION NOT IN ( SELECT SID FROM LOCK_1);

实现 Oracle 查找锁之间依赖关系的最源头SID  (首先得到锁的SID),再通过SID找sql查问题..
*** 思路
    
    1、证明有锁,需要满足v$session.BLOCKING_SESSION[阻塞会话的SID] IS NOT NULL and BLOCKING_SESSION_STATUS = 'VALID'条件;

    2、阻塞会话的SID 不在 SID 中就是最源头的SID (首先得到锁的SID);

    3、注意:v$session单实例,gv$session 多节点;


请使用浏览器的分享功能分享到微信等