一、基本原理
缓存在library cache中的对象我们称之为库缓存对象(library cache object),所有的库缓存对象都是以库缓存对象句柄(library cache object handle)的结构存储在library cache中,oracle通过访问库缓存对象句柄来访问库缓存对象。
oracle在访问库缓存对象时,需要先找到对应的bucket,然后获得lock,持有着lock去寻找该bucket下对应的handles,这个持有的过程就是library cache lock。在找到handle后,根据读取到的句柄中的信息去搜寻其他内存块地址时,此时持有library cache pin,直至操作完毕释放。 library cache lock针对的是handle,library cache pin 针对的是 heap;
在访问库缓存对象时,比如软解析时,要从库缓存中读取执行计划。Oracle首先找到句柄,读取句柄中的信息,这就叫做一次库缓存Get。如果库缓存中不包括对象的句柄信息,Oracle就要重新在库缓存中分配内存、构造句柄,这就是库缓存句柄未命中(Get Miss)。相反,如果在库缓存中找到了对象句柄,就是库缓存句柄命中(Get Hit)。硬解析时,就会发生Get Miss。而软解析则是Get Hit。在取出句柄中的其他内存块地址后,每访问一个内存块,都叫做一次库缓存Pin。如果相应的内存块已经不在内存中了,这就是Pin Miss,Pin的未命中。相反就是Pin Hit。
lock主要有三种模式: Null, share(2), Exclusive(3)。在读取访问对象时, 通常需要获取Null(空)模式以及share(共享)模式的锁定。在修改对象时,需要获得Exclusive(排他)锁定。
pin操作跟lock一样, 也有三种模式: Null, shared(2)和exclusive(3)。只读模式时获得 shared pin, 修改模式获得 exclusive pin。
模式为shared(2)的pin会阻塞任何exclusive(3)的pin请求。模式为shared(3)的pin也会阻塞任何exclusive(2)的pin请求。
所有的DDL都会对被处理的对象请求排他类型的lock和pin。
二、主要原因
- sql语句硬解析频繁或version count过高;
- 在繁忙事务期间执行DDL操作(比如统计信息收集动作、重新编译存储过程、包等);
模拟案例来源:http://t.askmaclean.com/thread-3066-1-1.html
创建测试用存储过程
- Create or replace procedure dummy is
- begin
- null;
- end;
- /
开启session 1,
Begin
Dummy;
Dbms_lock.sleep(1000);
End;
/
开启session 2
alter procedure dummy compile; => session 2 将会被 'library cache pin' 堵塞。
开启session 3
alter procedure dummy compile; => session 3 将会被 'library cache lock'堵塞。
开启session 4
select * from (select event,total_waits,time_waited,TIME_WAITED_MICRO,AVERAGE_WAIT,TOTAL_TIMEOUTS from v$system_event where wait_class <> 'Idle' order by 3 desc) where rownum<=50;
EVENT TOTAL_WAITS TIME_WAITED TIME_WAITED_MICRO AVERAGE_WAIT TOTAL_TIMEOUTS
------------------------------ ----------- ----------- ----------------- ------------ --------------
library cache pin 6 99458 994583184 16576.39 1
library cache lock 7 89630 896301556 12804.31 0
查询事件的阻塞者和持有者
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29319055/viewspace-2083770/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29319055/viewspace-2083770/