浅析:library cache lock和library cache pin

这两天研究了一下library cache lock和library cache pin,对其的认识更加清晰了一些。

 

在解读之前得说一些常识性的东西,方面之后理解:

首先library cache lock和library cache pin不是latch,我们可以把他看成一个内存里面的锁。

这两个“锁”也有自己的模式,就像TX锁有Row-S、exclusive(X)、Share(S)这些模式一样。

library cache lock和library cache pin是游标上面的争用,游标分为瞬时和存储性的,他们的“锁”能够拥有的模式是不同的。但是这个不是今天的重点。

lock可以持有的锁模式:0 、n、s、x(瞬时游标无S、X)

pin可以持有的锁模式:0、s、x

0模式:证明无锁

n模式:允许游标申请s、x时,我们称之为破碎解析锁,他与0的区别是,当sx模式的锁申请后,他会通告,自己被更“高级”的锁模式占用了

s模式:共享模式。允许其他游标申请S,但是不允许申请X

X模式:独占模式。拒绝其他对游标的申请。

 

其实从模式中我们就能看到。造成library cache lock和library cache pin锁的原因无非两种情况:

1.会话1持有S模式的锁(无论是lock还是pin),会话2申请X模式的锁。那么就要产生等待,等会话一释放S模式锁之后才行。

2.会话1持有X模式的锁(无论是lock还是pin),会话2申请X,S模式的锁。那么就要产生等待,等会话一释放X模式锁之后才行。

这两种情况如果是发生在申请LOCK的时候就是等待library cache lock当然,申请PIN的时候就是等待library cache pin。

OK,现在开始一些稍微深入的东西:

11g之后lock和pin一般都出现在存储过程上面,对象和表上面都较少了。

在SQL、存储过程等的编译阶段,需要的是获取父游标的句柄handel(个人觉得这个地方也可以理解为获取heap0,heap0是游标中的0号对,里面是此游标的元数据之类的信息,也可以认为就是handel),获取句柄这个动作其实就是申请lock,这个时候产生争用,那么,library cache lock来了。

之后在执行阶段,我们需要获取执行计划才能执行SQL吧,执行计划存储在子游标的heap6里面,这个时候我们就要去pin住heap6.如果产生争用,那么library cache pin来了。

这儿有一点要注意,编译阶段lock,执行阶段pin。lock是肯定在pin之前的。

这个仅仅是针对SQL和存储过程的,对象和表相关的与之类似。

现在,懂了吧?晕不晕?

最后我们想一下如何模拟这个现象。

会话1正在调用存储过程A。这个时候他将以n模式获取LOCK以及S模式获取PIN。

此时,会话2更改A,比如delete A,更改A内部代码,甚至grant这个存储过程的权限给其他用户,这个时候会以X模式获取LOCK,在获取之前,该存储过程游标lock的模式为会话1持有的n,那么会话2能够正常获取lock的x。但是该存储过程游标pin的模式为会话1持有的s。那么获取PIN的X就被堵塞了,只能等待。这个时候就产生了library cache pin。

继续,会话3在这个时候更改A,比如delete A,更改A内部代码,甚至grant这个存储过程的权限给其他用户,这个时候会以X模式获取LOCK,在获取之前,该存储过程游标lock的模式为会话2持有的x,那么会话2不能够正常获取lock的x,这个时候就产生了library cache lock。

可能有点绕,慢慢品味。哈哈。。。。

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注