必须用GV$ACTIVE_SESSION_HISTORY查RAC跨节点阻塞,因DBA_HIST_ACTIVE_SESS_HISTORY仅含当前实例聚合快照,90%阻塞源(如blocking_session在其他节点)会漏掉;关键条件为event='library cache lock'、wait_time=0、blocking_session IS NOT NULL,且需立即解析p3定位namespace与mode,并结合final_blocking_session穿透级联链直指根因。
DBA_HIST_ACTIVE_SESS_HISTORY 只存当前实例的聚合快照,RAC 下 90% 的阻塞源会漏掉——比如 blocking_session=1234 在节点 2 上,你在节点 1 查这个视图根本看不到。GV$ACTIVE_SESSION_HISTORY 才是跨实例实时采样的唯一可靠来源。
实操必须显式指定 inst_id 或用 -g all(如 oradebug),否则默认只查本节点。常见错误是直接 SELECT * FROM dba_hist_active_sess_history WHERE event = 'enq: TX%',结果为空却误判“没阻塞”。
ASH 里大量记录是 CPU 运行或空闲状态,不加筛选会淹没真实阻塞信号。library cache lock 或 enq: TX% 等待事件必须配合 wait_time = 0(表示正卡着,不是刚结束),再叠加 blocking_session IS NOT NULL 才能定位到“正在被谁拦住”。
时间窗必须压窄:SAMPLE_TIME > SYSDATE - 3/1440(最近 3 分钟)。ASH 内存 buffer 默认约 60 分钟,但越早的数据越可能被覆盖;查太宽不仅慢,还容易混入已释放锁的残留快照。
event = 'library cache lock' AND wait_time = 0 AND blocking_session IS NOT NULL AND sample_time > SYSDATE - 3/1440
blocking_session 在 RAC 中常指向本节点的中间阻塞者,比如 A→B→C 链中,你看到 B 阻塞 C,但 B 其实是被节点 2 上的 A 阻塞。final_blocking_session 和 final_blocking_instance 是 Oracle 12c+ 引入的穿透字段,跳过中间层直指源头。
查到 final_blocking_session = 5678 后,不能直接 kill,得立刻连到 final_blocking_instance 对应的节点,查 v$session 确认该 SID 是否 still ACTIVE:
SELECT instance_number FROM gv$instance WHERE instance_name = 'rac2' 校验实例号是否有效SELECT sid, serial#, username, status, sql_id, event FROM v$session WHERE sid = 5678
v$transaction 或 dba_hist_active_sess_history 回溯长事务library cache lock 的 p3 是十六进制复合值,格式为 100 * mode + namespace。不 decode 就查 SQL,90% 会走偏——比如 p3=0x4f0003 表示 mode=3(独占)、namespace=79(ACCOUNT_STATUS),实际是登录风暴,跟 SQL 完全无关。
解码后立即分路径排查:
v$sqlarea 中 version_count > 50 且 executions < 10 的游标,大概率硬解析风暴dba_objects 的 last_ddl_time 是否集中在故障时段dba_audit_session 查 returncode = 1017 高频失败登录RAC 下 p3 解码结果必须结合 blocking_instance 判断锁发生在哪个节点的共享池,不能只看本节点数据。