2015.06.03
查看生产库的等待事件的时,经常看到 cursor: pin S 等待事件
这是一个由于频繁执行SQL共享解析时产生的竞争。当一个会话尝试以共享模式(S - Share)来获得一个游标时,需要修改相应的Mutex结构的引用计数(reference count),或者增加该计数,或者减少。修改引用技术的原子操作很快(其实和Latch的获取释放类似),但是在频繁解析的情况下,仍然产生了竞争和等待,由此就产生了 cursor : pin S 的等待。
下面语句找到引起 cursor: pin S等待事件的具体SQL:
点击(此处)折叠或打开
-
SELECT a.*, s.sql_text
-
FROM v$sql s,
-
(SELECT sid,
-
event,
-
wait_class,
-
p1 cursor_hash_value,
-
p2raw Mutex_value,
-
TO_NUMBER (SUBSTR (p2raw, 1, 8), \'xxxxxxxx\') hold_mutex_x_sid
-
FROM v$session_wait
-
WHERE event LIKE \'cursor: pin S\') a
- WHERE s.HASH_VALUE = a.cursor_hash_value;
这通常是由于某些SQL以超高频繁的频率执行导致的,当然也可能与系统的CPU能力不足有关。
结合该库的实际情况,确定为某些SQL超高频繁的执行导致的,应该是程序员或者数据库开发人员将SQL写到循环里导致的,超高频执行,算了一下业务高峰期时大概每分钟,每个SQL执行10万次。
Mutex机制在Oracle 10g引入,用于替代Library cache pin操作,其性能更高,其原理为在每个Child Cursor上分配一个地址空间记录Mutex,当该Cursor被共享执行时,通过将该位进行加一处理来实现。虽然是指游标共享,但是更新Mutex结构的操作需要排他,当某一个SQL被频繁共享执行时,可能就会出现Pin S的等待。
每个Library Cache对象都有一个reference count (引用计数),用来表明有多少其他对象目前正保留一个对它的引用(reference). 对象A 想要引用对象B, A 就把B 的 reference count 加 1。 当A 结束了对B 的引用, A 就把 B 的reference count 减 1. 当没有任何对象再引用 B 时, B 的 reference count就减为0, B 就被清除(deallocated), 内存就被释放。清除B的时候, 被B所用的对象的 reference count 也可能减小, 也可能使它们被清除。
最简单的解决方案是,将频繁执行的SQL分区拆解,分散竞争。