v$active_session_history可回溯1小时内每秒的锁等待,需查event含'enq: %'且session_state='WAITING'、wait_class='Concurrency'的记录,结合p1/p2解码定位具体锁对象。
如何用v$active_session_history查Blocked Session
ash不是实时视图,但它是诊断锁等待最可靠的“回溯依据”——尤其当阻塞已结束、v$session里找不到blocking_session时,ash能还原过去1小时内每秒的会话状态。
关键点:ASH只记录ACTIVE会话,且采样间隔默认1秒;若会话在采样瞬间处于enq: TX - row lock contention或enq: TM - contention等等待事件中,就会留下痕迹。
- 必须确保
STATISTICS_LEVEL = 'TYPICAL'或'ALL'(BASIC会禁用ASH) - 查询范围受限于ASH buffer大小(通常几MB),默认最多保留约30分钟数据,超时即被覆盖
- 不能直接查“谁被谁锁”,需结合
blocking_session和blocking_session_serial#字段反向关联
常用SQL:
SELECT sample_time,
session_id,
session_serial#,
blocking_session,
blocking_session_serial#,
event,
p1text, p1,
p2text, p2,
sql_id
FROM v$active_session_history
WHERE event LIKE 'enq: %'
AND sample_time > SYSDATE - 1/24 -- 查最近1小时
ORDER BY sample_time DESC;为什么v$session.blocking_session有时为空却仍有锁等待
常见现象:执行SELECT * FROM v$session WHERE blocking_session IS NOT NULL返回空,但业务明显卡顿、应用日志报超时。这往往是因为阻塞已解除,但锁等待过程短暂而密集,v$session快照没捕获到那一瞬。
根本原因在于v$session是动态视图,内容随会话状态实时刷新;而ASH是内存中滚动采样的历史快照,只要采样时刻会话正在等锁,就一定有记录。
-
v$session.blocking_session只反映“当前”阻塞关系,毫秒级变化都可能错过 - ASH中
blocking_session字段同样可能为NULL——不是没阻塞,而是采样时阻塞源刚好完成提交或回滚 - 真正可靠的是
event+session_state = 'WAITING'+wait_class = 'Concurrency'三者组合
ASH中识别TX/TM锁等待的关键字段
Oracle锁等待事件在ASH里以enq:前缀标识,但仅看event列不够,必须结合p1、p2解码资源ID,才能定位具体对象或行。
-
event = 'enq: TX - row lock contention':典型行锁,p1是锁类型+模式(高16位为type,低16位为mode),p2是usn -
event = 'enq: TM - contention':表级锁,p1是object_id,可联dba_objects查表名 -
p3在TX锁中常为row_wait_file# - 不要依赖
current_obj#字段判断锁定对象——它反映的是当前SQL访问的对象,不一定是锁持有对象
快速定位被锁表:
SELECT DISTINCT o.object_name, o.object_type FROM v$active_session_history h JOIN dba_objects o ON h.p1 = o.object_id WHERE h.event = 'enq: TM - contention';
对比v$lock和ASH:什么情况下该信哪个
v$lock告诉你“此刻谁持有什么锁”,ASH告诉你“过去谁在等什么锁”。两者不是替代关系,而是时间维度互补。
- 刚收到告警、问题仍在发生 → 优先查
v$lock+v$session,找实时阻塞链 - 告警已过、用户反馈“刚才卡了两分钟” → 必须查
ASH,否则线索消失 -
v$lock里block = 1的会话未必还在运行,可能已断开但事务未清理(需查v$transaction) - ASH里频繁出现同一
sql_id+ 同一event,说明该SQL存在结构性锁风险,不是偶发
最容易被忽略的一点:ASH中session_state = 'ON CPU'的会话,也可能正在做锁竞争后的重试循环(比如应用层无退避的UPDATE重试),不能只盯WAITING状态。


















