引言:
等待事件其实我是不想过多描述的,因为现在市面上涉及OWI方法论,等待事件解决方法论的书籍比比皆是,包括vage大师在oracle内核揭秘中已经给出了很好的诠释,
总觉得这篇文章有点画蛇添足,但还是希望透过这篇文章,在我个人对oracle等待事件理解的基础上,或许能够给大家带来不一样的troubleshooting的思路。同时,
本人真的不觉得,我能比别人把这个等待事件描述的更清楚。
1.认识cursor pin s wait on X等待事件:

1.1 概念介绍:
当会话请求共享shared mutex pin,而另一个会话在同一个游标对象上持有exclusive mutex pin时,会话将等待此事件。其实,cursor:pin S wait on X与11g新的mutex机制有着千丝万缕的关系,Oracle官方宣称mutexes的速度更快,并且通过library cache latch能够更好的提高并发性,因为mutex的代码路径很短,使用的cpu更少,对于CPU-bound绑定的数据库相对比较重要,因为在这样的数据库设计理念中,大量的buffer cache产生的i/o可能成为主要的争用资源。
1.2 相关参数说明:
1.2.1.P1:Hash value of cursor 游标的hash value
1.2.2.P2:Mutex value前两个字节包含以独占模式持有互斥的SID,后两个字节通常持有0
1.2.3.互斥对象(内部代码定位器)或互斥对象所在的位置
注意事项:
首先,我们可以明确游标等待与某种形式的解析相关联。当会话试图在共享模式中获取互斥锁pin时,会话可能会等待此事件发生,但另一个会话会以独占的方式持有相同游标对象上的互斥锁pin。通常,等待“cursor:pin S wait on X”是一种症状,而不是原因。我的经验是可能存在潜在的调优需求或已知问题而已。
简单说,就是进程为了共享操作,执行pin cursor游标,并且通过shared mode模式申请了mutex,然后呢,这个进程没有立即获得,原因是因为这个进程想要去 获取的游标被另一个进程通过独占模式持有了。
1.3 可能造成此等待事件的原因:
1.3.1首先,我们要确保shared pool共享池的内存是足够大的。
1.3.2频繁的硬解析,如果硬解析的频率非常高,那么在这个pin上可能会发生争用
1.3.3游标版本号比较高,也就是说当版本计数过多时,需要在library cache库缓存里遍历长长的游标版本,这可能导致在此事件上的争用
1.3.4相关数据字典查询,比如x$固化视图,或者v$动态性能视图,相关的fixed table,有可能会触发mutex争用情况
1.3.5mutex互斥锁,压根申请不到cpu资源,例如我们使用了资源管理器resource manager,在任务窗口限制了消费者对应进程使用cpu资源的情况。
1.3.6可能我们已经immediate killed了进程,该进程已经是killed状态,这时,假设session正在持有mutex,然后我们kill -9掉了对应的操作系统进程,
则知道pmon彻底清理掉这个僵死进程并释放mutex,其他进程才能不必等待,当然也可能是bug行为导致的pmon去清理进程速度变慢的行为。
1.4 简单描述在1.3.6中提到的情况:
1.4.1 一个会话被干掉,PMON会介入并清理会话。PMON可以尝试清理相同的互斥锁,但没有成功,然后一遍又一遍地不清理导致等待的其他进程
library cache: mutex X了
1.4.2 然后pmon trace文件会反复打印如下消息

2.模拟一下这个cursor pin s wait on x的等待事件:

2.1 session 1 如下操作:

2.2 session 2 如下操作:

2.3 gdb显示breakpoint kxsPeekBinds窥视绑定值信息print出来:

2.4 session 3 如下操作:

2.5 session 4 如下操作:

2.6 session 5 如下操作:

2.7 session 6 如下操作:




注意了,这些location位置代码其实是存放在kksc中的。还是session 4或者session 5作如下查询:

别着急,我们随便找个空闲的session,做systemstate级别为266收集工作:

3.trace文件分析:



4.问题定位思路:

4.1 awr报告或者ash报告
4.2 非rac环境出现hang情况执行如下命令:

4.3 rac环境

4.4 找到阻塞的的ospid,生成一个errorstack

4.5 systemstate/hanganalyze/errorstack是非常考验DBA段位的,严格意义来讲,可能大部分DBA是看不懂的,那如何解决问题呢?
4.5.1当请求互斥对象进行与pin相关的可共享操作(比如执行游标)时,会话会等待这个事件,但是不能授予互斥对象,因为互斥对象仅由另一个会话持有(很可能是解析游标)。
这个时候,我们有必要查询一下数据字典信息:
注意:v$session或v$session_wait中的列P2RAW给出了等待事件指针的阻塞会话:pin S wait on X。
p2raw的顶部字节是块体。它是十六进制的,所以需要用十进制换算。比如下面的查询,大家可能是看不懂的
select p2raw from v$session where event = 'cursor: pin S wait on X';
P2RAW
----------------
0000001F00000000
注意:
使用0000001F(前8个字节)并将其转换为decimal可得到session id,例如下面的查询:

4.6 阻塞会话可以被查询
我们主要是查看它在做什么,以及是否有人阻塞它,例如下面的查询:

4.7 Oracle11g与Oracle12c
直接使用以下sql找到阻塞会话:

5.AWR主要关注指标:
5.1 SQL Statistics下主要关注,SQL by Parse Calls或SQL by Version Count指标:


5.2 通过Load Profile我们来验证执行和解析,硬解析情况:

5.3 通过实例命中率指标,关注软解析情况:

6.mutex的bug
下面为大家总结了一些常见的bug行为,如果命中,不妨去查一查





关于cursor pin s wait on x的工作原理,试验,包括问题处理的方式方法基本就这么多,希望可以帮助到大家。
<点亮梦想.拒绝平庸>
