Oracle 11g+可直接通过v$session和ASH的blocking_session字段定位cursor: pin S wait on X阻塞源头,无需解析p2raw;需结合v$sqlarea和v$sql_shared_cursor分析游标碎片化根因。

直接查 blocking_session 字段就能定位源头
Oracle 11g 及以后版本(含 19c)在 v$session 和 dba_hist_active_sess_history 中已原生支持 blocking_session 字段,不用再手动解析 p2raw。只要看到等待事件是 cursor: pin S wait on X,它的 blocking_session 值就是真正持 X 锁的会话 ID —— 这个会话正在硬解析、刷新执行计划或修改游标元数据。
执行这条语句快速抓出当前活跃阻塞链:
SELECT sid, sql_id, blocking_session, event, program FROM v$session WHERE event = 'cursor: pin S wait on X' AND blocking_session IS NOT NULL;
注意:若返回为空,说明阻塞已结束或当前无实时等待;此时必须查历史 ASH。
用 dba_hist_active_sess_history 回溯指定时间窗口
生产环境问题往往转瞬即逝,等你登录时等待已消失。必须依赖 ASH 历史记录。关键不是查“谁在等”,而是查“谁被等”——即 blocking_session 非空的那些行,再反向追踪它当时在做什么。
- 先锁定问题时间段,比如应用反馈卡顿的 14:00–14:15
- 用
sample_time过滤,避免跨快照引入噪声 - 只取
blocking_session IS NOT NULL的记录,这是真实源头
示例查询:
SELECT DISTINCT s.blocking_session, s.sql_id, t.sql_text FROM dba_hist_active_sess_history s JOIN dba_hist_sqltext t ON s.sql_id = t.sql_id WHERE s.event = 'cursor: pin S wait on X' AND s.sample_time BETWEEN TIMESTAMP '2026-10-27 14:00:00' AND TIMESTAMP '2026-10-27 14:15:00' AND s.blocking_session IS NOT NULL AND ROWNUM <= 5;
别只看 SQL 文本,重点查 version_count 和 bind_mismatch
拿到源头 sql_id 后,不能只看语句长得简单就放松警惕。真正导致游标争用的是它在共享池中分裂了多少个子游标,以及为什么分裂。
立刻查这三件事:
-
SELECT version_count, loaded_versions, users_executing FROM v$sqlarea WHERE sql_id = '<sql_id>'</sql_id>—— 若version_count > 5,基本坐实游标碎片化 SELECT child_number, bind_mismatch, optimizer_mismatch FROM v$sql_shared_cursor WHERE sql_id = '<sql_id>' AND ROWNUM —— 找出第一个 <code>bind_mismatch = 'Y'的子游标,这就是软解析失败的起点- 检查该 SQL 是否在 PL/SQL 中用
EXECUTE IMMEDIATE拼接,且绑定变量未显式声明类型(如VARCHAR2(32)vsVARCHAR2(1))
P2 值解析仅作备用,19c 中多数情况不需要
虽然文档里说 P2 高位存持锁 SID,但 19c 已全面支持 blocking_session,且更准确。只有两种情况才需手动拆 p2:
- 查的是 10.2–11.2 的老库,
blocking_session字段不存在 - ASH 中某条记录的
blocking_session为 0 或空,但p2raw非零,此时可能是后台进程(如ora_q000_<inst></inst>)在做统计信息收集
64 位库解析方法(仅当真要用):
SELECT TRUNC(&p2 / 4294967296) AS sid_holding_x_pin FROM dual;
真正容易被忽略的点是:即使定位到源头 SQL,如果没查 v$sql_shared_cursor 确认具体哪一列是 Y,就盲目调大 shared_pool_size 或重启实例,只会掩盖问题——游标还是会继续分裂,下次照样等。


















