应使用dba_hist_active_sess_history回溯1–3分钟前的阻塞会话,关键过滤sample_time和event,并用final_blocking_instance/session定位RAC跨节点根阻塞源;p1raw后两位区分mode=4(唯一键/ITL冲突)与mode=6(行锁等待)。

直接查ASH历史会话,别只盯v$session
v$session只反映“此刻”谁在等,但真实阻塞往往发生在1–3分钟前——等你登录进去,持锁会话可能已提交或断开。必须用dba_hist_active_sess_history回溯。默认保留1小时数据(Oracle 19c),超时自动滚动丢弃,别查超过60分钟的范围。
关键过滤条件要写全:WHERE event = 'enq: TX - row lock contention' AND sample_time BETWEEN TIMESTAMP '2026-09-17 22:30:00' AND TIMESTAMP '2026-09-17 22:35:00'(注意用数据库所在时区,不是本地时间)。
常见错误是漏掉sample_time范围,直接SELECT * FROM dba_hist_active_sess_history——轻则卡住SQL*Plus,重则因权限不足报ORA-00942: table or view does not exist。
用final_blocking_instance和final_blocking_session定位根阻塞者
RAC环境下,blocking_session字段不可靠,它只返回本实例内的会话ID;真正跨节点的阻塞源藏在final_blocking_instance和final_blocking_session里。
执行这个查询:
SELECT sample_time, inst_id, session_id, final_blocking_instance, final_blocking_session, sql_id, current_obj# FROM gv$active_session_history WHERE sample_time > SYSDATE - 5/1440 AND event = 'enq: TX - row lock contention' AND final_blocking_session IS NOT NULL AND final_blocking_instance IS NOT NULL ORDER BY sample_time DESC;
如果final_blocking_session返回0或空值,说明它是根阻塞源(比如一个没提交的批处理事务);如果final_blocking_instance和当前inst_id不同,就确认是跨节点阻塞——单实例脚本根本查不到。
从p1raw解析锁模式,区分mode=4和mode=6
等待事件本身不告诉你冲突类型,得看p1raw字段。它是个16进制值,前4位固定是5458(TX),后2位决定模式:
-
54580006→ mode=6:标准行锁等待,A更新某行未提交,B想更新同一行被堵 -
54580004→ mode=4:大概率是唯一键冲突或ITL槽不足,不是真“锁了某行”,杀等待者没用
查持锁者时,别只看blocking_session,要结合p2(usn)和p3(slot+sqn)反查v$transaction,再连到v$session确认status——INACTIVE且logon_time很老的会话,90%是应用异常退出没清理事务。
别跳过resource_name2,它藏着事务级根因
在RAC中,仅靠enq: TX - row lock contention判断太浅。真正循环等待常藏在gv$ges_blocking_enqueue的resource_name2里,比如事务号、回滚段号。
执行:
SELECT inst_id, event, state, blocking_inst_id, resource_name1, resource_name2, sid, serial#
FROM gv$ges_blocking_enqueue
WHERE state IN ('BLOCKING', 'WAITING');resource_name1形如TX-000A0001-00000F4C,不是表名,需用TO_NUMBER('00000F4C','XXXXXXXX')转成十进制后查dba_objects;而resource_name2里的值(如0000000000000000)可能对应具体事务XID,这才是跨实例死锁链的锚点。
最容易被忽略的是:mode=4的等待,resource_name2往往指向同一个唯一键值或ITL槽地址——这时候优化方向不是杀会话,而是加前置校验、调大INITRANS或拆分热点块。


















