必须用GV$ACTIVE_SESSION_HISTORY,因其每秒采样、含blocking_instance和blocking_session字段,可精准定位RAC跨节点的library cache lock根阻塞源;过滤条件为event='library cache lock'、wait_time=0、blocking_session IS NOT NULL,并须立即解析p3解出namespace与mode以确定排查路径。

必须用 GV$ACTIVE_SESSION_HISTORY,别只查当前实例
在 RAC 环境下,library cache lock 的阻塞源很可能来自其他节点。如果只查 DBA_HIST_ACTIVE_SESS_HISTORY 或单实例的 V$ACTIVE_SESSION_HISTORY,90% 的阻塞链会漏掉——因为 blocking_session 字段可能指向另一个实例的会话,而该会话根本不在当前实例的视图里。
正确做法是:强制使用 GV$ACTIVE_SESSION_HISTORY,并显式带上 blocking_instance 或加条件 blocking_instance IS NOT NULL。否则你看到的只是“中间阻塞者”,不是根因。
- 时间窗口务必压到 3–5 分钟内,例如:
SAMPLE_TIME > SYSDATE - INTERVAL '5' MINUTE(避免写死时间字符串,受时区和 NLS 影响) - 关键过滤条件只有三个:
event = 'library cache lock'、wait_time = 0(表示正卡着,非历史采样)、blocking_session IS NOT NULL - 不要依赖
DBA_HIST_ACTIVE_SESS_HISTORY做实时排查——它采样稀疏、聚合过、且默认只含当前实例数据
P3 值必须立刻解出 namespace 和 mode
P3 是十六进制整数,格式为 100 * mode + namespace,但实际存储是高位拼接,需按字节拆解。比如 P3 = 61959198277635 转成十六进制是 385a00010003,其中:
- 高 4 字节
385a→object_id = 14426(可查DBA_OBJECTS定位对象) - 中间 4 字节
0001→namespace = 1(对应CRSR,即游标) - 低 4 字节
0003→mode = 3(独占锁,X 模式)
不同 namespace 决定排查路径:
-
namespace = 1(CRSR)→ 查V$SQL中version_count > 50且executions极低的 SQL,大概率是绑定变量为空或 ACS BUG 引发子游标爆炸 -
namespace = 2(TABLE/PROCEDURE)→ 查DBA_OBJECTS的last_ddl_time是否集中在问题时段,怀疑 DDL 阻塞 -
namespace = 79(ACCOUNT_STATUS)→ 不是 SQL 问题,是登录风暴,立刻查DBA_AUDIT_SESSION中returncode = 1017(密码错)高频重试
查到 blocking_session 后必须切到对应节点确认
GV$ACTIVE_SESSION_HISTORY 是采样视图,只能告诉你“当时谁在阻塞”,不能保证该会话当前仍持锁。比如查到 blocking_instance = 2、blocking_session = 1058,下一步必须立刻连上节点 2 执行:
SELECT sid, serial#, username, status, sql_id, event, blocking_session, sql_exec_start FROM v$session WHERE sid = 1058;
重点看:
-
status是否为ACTIVE(已 INACTIVE 就说明锁早释放了) -
event是否仍是library cache lock或已转为cursor: mutex X等衍生等待 -
sql_exec_start是否远早于当前时间(说明该 SQL 已执行很久,可能正在做 DDL 或大解析) - 若
sql_id为空,且username是应用账号,要警惕认证类争用(如namespace=79场景)
区分真 SQL 问题和假性争用
大量 library cache lock 并不总意味着某条 SQL 有问题。常见干扰项包括:
- 统计信息自动收集任务与业务 SQL 时间重叠:AUTO SQL TUNING 或 GATHER_STATS_JOB 在刷共享池,导致所有新解析都排队
- 应用端频繁
ALTER SESSION SET CURRENT_SCHEMA:每次切换 schema 都触发一次 library cache 重载 - 绑定变量类型不稳定:比如
VARCHAR2绑定空值(Bug 8198150),导致每条空值生成独立子游标,V$SQL中version_count达数千甚至上万 - 共享池过小或未启用
RESULT_CACHE,导致硬解析密集,加剧 mutex 争用
验证是否为绑定空值引发:查 V$SQL_BIND_CAPTURE 中该 sql_id 对应的 datatype_string 和 value_string,若出现大量 NULL 且类型为 VARCHAR2,基本可锁定。


















