关于等待事件cursor: pin S的一点介绍

来源:互联网 发布:centos 6.5 hadoop 编辑:程序博客网 时间:2024/05/17 23:14

 《早期博客迁移博文》

今天下午客户的系统遇到了cursor: pin S等待事件,与之伴随的是CPU居高不下,idle几乎为零,通过查看等待事件发现有近20个cursor: pin S等待事件,见下:

EVENT                                                              COUNT(*)
—————————————————————- ———-
db file sequential read                                                   1
gc cr request                                                             3
jobq slave wait                                                           1
SQL*Net message to client                                                 1
gcs remote message                                                        4
SQL*Net message from client                                             227
latch free                                                                2
smon timer                                                                1
pmon timer                                                                1
CSS operation: action                                                     1
DIAG idle wait                                                            1
rdbms ipc message                                                        14
ges remote message                                                        1
Streams AQ: qmn slave idle wait                                           1
latch: cache buffers chains                                               1
Streams AQ: qmn coordinator idle wait                                     1
cursor: pin S                                                            19
Streams AQ: waiting for time management or cleanup tasks                  1
18 rows selected.

再通过查询持有的等待事件cursor: pin S的会话正在执行的SQL语句发现仅是一条简单的SQL:

SELECT X.BUSINESSID FROM SYS_BUSINESS X WHERE X.BUSINESSCODE=:B1

SELECT语句涉及的表SYS_BUSINESS数据量本身也不是很大,目前总共有77条数据,通过询问应用人员了解到该表日后数据量也几乎不会有大的增加(应该是某业务模块的的一个基表)。

通常内存中latch pin操作是相当快的,如果出现等待了,应该很可能就是该SQL执行的过于频繁;要不就是CPU的计算效率跟不上(这个是HP的小机,也算可以了,本例中不会是这种因素)。在Oracle官方文档中介绍说:

crusor: pin S

A session waits on this event when it wants to update a shared mutex pin and another session is currently in the process of updating a shared mutex pin for the same cursor object.This wait event should rarely be seen because a shared mutex pin update is very fast.

我们知道latch在Oracle中是一种低级锁,用于保护内存里的数据结构,提供的是串行访问机制,而mutex是Oracle 10gR2引入的,也是为实现串行访问控制的功能,并替换部分latch。 在http://www.uml.org.cn上有段话写的很明了:

Mutex中有两个变量:分别是Holder identifer和Reference count,Holder identifier记录持有mutex的SID,而Reference count是一个计数,记录了当前正在以share方式访问mutex的数量,每当session以share方式持有mutex时,计数会加1,而释放时该计数会减1。所以,如果Reference count大于0,则表示该内存结构正在被Oracle pin住。

一个session持有cursor: pin S说明该session正在某一个cursor上以S(Share)方式请求mutex,但是又不能立即获得该mutex。不过在很多情况下,我们可能会发现并没有其他concurrent session在这个cursor上持有X(eXclusive) mode mutex,或许感觉很奇怪,请继续往下看,不过为保持“原味”并避免个人曲解Oracle意思而误导大家,贴如下原文:

A session waits for “cursor: pin S” when it wants a specific mutex in S(share) mode on a specific cursor and there is no concurrent X holder but it could not acquire that mutex immediately.This may seem a little strange as one might question why there should be any form of wait to get a mutex which has no session holding it in an incompatible mode.The reason for the wait is that in order to acquire the mutex in S mode (or release it) the session has to increment(or decrement) the mutex reference count and this requires an exclusive atomic update to the mutex structure itself.If there are concurrent sessions trying to make sure an update to the mutex then only one session can actually increment(or decrement) the reference count at a time.A wait on “cursor: pin S” thus occurs if a session cannot make that atomic change immediate due to other concurrent requests.

本人大胆翻译下,如有错误望指出:

主要意思就是说:一个session以S(Share)模式获取mutex或者释放mutex时,该session必须增加(+1)或者减少(-1)mutex’s reference count,而这个加减操作该session是以X(eXclusive)方式更新Mutex结构,也即该session更新mutex reference count的过程中是不允许任何session访问的。一次只能有一个session能够增加(increment)或者减少(decrement)mutex’s reference count,所以如果在并发量特别大的情况,处于等待状态的session就会出现此等待事件(cursor: pin S)。

基于上面的了解,接着看我的case,通过收集AWR报告,前五的等待事件为:

cursor: pin S占到db time的16%,再看执行次数较多的SQL语句:

主要关注第一行即可,可以清楚的看到,在过去的一个小时内,SQLID为88znsq01mjwns的SQL语句执行了256,024,463次,高达2亿5千万余次,平均每秒执行7万余次,我的神…,你说这执行次数算高么?系统出现19个cursor: pin S等待事件,个人感觉Oracle已经很给面子了,呵呵,开玩笑。

该SQL语句与文章开头给出的SQL是同一条语句,已经将该SQL发给应用研发人员进行评估并做业务逻辑调整。

原创粉丝点击