一聚教程网:一个值得你收藏的教程网站

热门教程

怎样使用Oracle ASH定位RAC跨实例阻塞

时间:2026-08-14 10:52:49 编辑:袖梨 来源:一聚教程网

必须用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穿透级联链直指根因。

必须用 GV$ACTIVE_SESSION_HISTORY,别查 DBA_HIST_ACTIVE_SESS_HISTORY

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%',结果为空却误判“没阻塞”。

  1. 单节点查:SELECT inst_id, sample_time, session_id, event, blocking_instance, blocking_session FROM gv$active_session_history WHERE ...
  2. RAC 全局查:SELECT * FROM gv$active_session_history WHERE inst_id IN (SELECT instance_number FROM gv$instance)
  3. 权限不足时,先确认你有 SELECT ON GV_$ACTIVE_SESSION_HISTORY,不是只给了 DBA_ 视图权限

关键过滤条件只有三个:event、wait_time=0、blocking_session IS NOT NULL

ASH 里大量记录是 CPU 运行或空闲状态,不加筛选会淹没真实阻塞信号。library cache lock 或 enq: TX% 等待事件必须配合 wait_time = 0(表示正卡着,不是刚结束),再叠加 blocking_session IS NOT NULL 才能定位到“正在被谁拦住”。

时间窗必须压窄:SAMPLE_TIME > SYSDATE - 3/1440(最近 3 分钟)。ASH 内存 buffer 默认约 60 分钟,但越早的数据越可能被覆盖;查太宽不仅慢,还容易混入已释放锁的残留快照。

  1. 错例:WHERE event LIKE 'enq: TX%' —— 漏了 wait_time = 0,会捞出大量已结束等待
  2. 错例:WHERE blocking_session IS NOT NULL —— 没限定 event 和时间,结果含大量断连僵尸会话
  3. 正确组合:event = 'library cache lock' AND wait_time = 0 AND blocking_session IS NOT NULL AND sample_time > SYSDATE - 3/1440

final_blocking_session 才是 RAC 下真正的根因字段

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:

  1. 先执行:SELECT instance_number FROM gv$instance WHERE instance_name = 'rac2' 校验实例号是否有效
  2. 再连目标节点查:SELECT sid, serial#, username, status, sql_id, event FROM v$session WHERE sid = 5678
  3. 若查不到或 status = 'INACTIVE',说明它已提交/回滚,需转向 v$transactiondba_hist_active_sess_history 回溯长事务

p3 值必须当场解码,否则 library cache lock 方向全错

library cache lock 的 p3 是十六进制复合值,格式为 100 * mode + namespace。不 decode 就查 SQL,90% 会走偏——比如 p3=0x4f0003 表示 mode=3(独占)、namespace=79(ACCOUNT_STATUS),实际是登录风暴,跟 SQL 完全无关。

解码后立即分路径排查:

  1. namespace=1(CRSR):查 v$sqlareaversion_count > 50executions < 10 的游标,大概率硬解析风暴
  2. namespace=2(TABLE/PROCEDURE):查 dba_objectslast_ddl_time 是否集中在故障时段
  3. namespace=79(ACCOUNT_STATUS):跑 dba_audit_sessionreturncode = 1017 高频失败登录

RAC 下 p3 解码结果必须结合 blocking_instance 判断锁发生在哪个节点的共享池,不能只看本节点数据。

热门栏目