查v$active_session_history定位library cache pin需同时满足event='library cache pin'、in_hard_parse='Y'、blocking_session IS NOT NULL且sample_time在2分钟内,再通过p1raw关联x$kglob查对象名,并区分pin与lock等待链。
直接看 v$active_session_history 里 event = 'library cache pin' 的记录,但只查这个字段会漏掉关键上下文——真正卡住的会话往往没在等,而是在持 pin 不放。
查ASH必须带in_hard_parse = 'Y'和blocking_session IS NOT NULL
Library cache pin 等待常由硬解析触发,但ASH默认不标出解析状态。不加过滤会混入大量无效采样:
-
in_hard_parse = 'Y'是定位 pin 持有者的最短路径,它比event字段更早、更准 -
blocking_session IS NOT NULL排除“自己等自己”的伪阻塞(比如单会话递归调用) - 时间范围建议缩到 2 分钟内,因为 pin 持有通常比 lock 更短暂,ASH 采样可能错过
- 示例查询:
SELECT sql_id, session_id, blocking_session, in_hard_parse, sample_time FROM v$active_session_history WHERE event = 'library cache pin' AND in_hard_parse = 'Y' AND blocking_session IS NOT NULL AND sample_time > SYSDATE - 2/1440;
从p1raw反推被pin的对象类型和地址
p1raw 是十六进制 handle 地址,不能直接 decode,但能交叉验证是否为热点对象:
- 用
SELECT kglhdadr, kglnaobj FROM x$kglob WHERE kglhdadr = HEXTORAW('...')查对应对象名(注意:x$kglob 需 SYS 权限) - 若多个等待行的
p1raw相同,且sql_opname IN ('CREATE', 'ALTER', 'DROP'),基本锁定是 DDL 编译卡在 pin 阶段 - 若
p1raw不同但kglnaobj都指向同一张表(如CONFIG_PARAMS),说明该对象被高频访问,pin 冲突来自并发查询而非 DDL - RAC 环境下,
p1raw在不同节点值不同,必须用GV$ACTIVE_SESSION_HISTORY全局查
区分library cache pin和library cache lock的等待链
两者表现相似,但根因机制完全不同,混查会误导排查方向:
-
library cache lock是对象级排他控制,常见于 DDL 执行中;library cache pin是 handle 级内存保护,多见于硬解析或 PL/SQL 执行时 - 持锁会话(
blocking_session)的event若为library cache lock,而等待者是library cache pin,说明 DDL 已卡住,后续所有对该对象的访问都会被 pin 阻塞 - 若持 pin 会话的
sql_text含EXECUTE IMMEDIATE或动态 SQL,且in_hard_parse = 'Y',大概率是应用层拼接 SQL 导致的解析风暴 - 不要依赖
v$sqlarea.version_count判断——pin 冲突时子游标可能未生成,v$sql_shared_cursor里UNBOUND_CURSOR = 'Y'反而是更可靠的信号
真正难处理的是那种 p1raw 指向系统包(如 DBMS_OUTPUT)却查不到具体 SQL 的 case,这往往意味着 PL/SQL 匿名块里嵌套了未命名的动态语句,得靠 DBMS_MONITOR.SESSION_TRACE_ENABLE 捕获完整调用栈,而不是在 ASH 里反复筛。


















