Librarycache的PIN与LOCK

2014-11-24 17:06:36 · 作者: · 浏览: 0

Library cache的PIN与LOCK

一、详述Library cache lock与Library cache pin

1. Library cache lock与Library cache pin的模式。

所有在Library cache中的对象,都由两部分组成,一个句柄、至少一个子堆。句柄中记录有对象的名字、命名空间、Lock的持有者和等待者、Pin的持有者和等待者、一些标志信息和子堆0的地址。

Locks 除了阻止不相容的对句柄的访问外,获得Locks也是在缓存中定位对象的唯一方式--进程定位并且锁一个对象在一个单一的操作中(即:锁和定位是在一个操作中完成的,它们是一体的)。

在句柄上获得Lock后,对象可以Pin自己。如果对象相关信息不在内存中,Pinning一个对象将导致它和它的的子堆被装载(此种情况时,如果是多个对象Pin一个对象,将可能会造成Pin等待)

Lock 有三种模式

· Share(s) : 读对象

· Exclusive(x) : 修改或创建对象

· Null(n) : 专用于为会话持续

注意:存贮对象可以被锁在以上任意一种方式,瞬时对象只能被锁在Null方式。

Null 锁在执行SQL声明的解析阶段被获得,此后一直持有。它不阻止任何DDL。也用术语“易碎解析锁”称乎它(breakable parse lock)。

在以下两种情况下Null锁被打碎:

·当锁所在对象有一个独占Pin时

·锁所在对象的任何依赖对象有一个独占Pin时

例9:分别做试验,察看正在打开的游标,其所依赖对象无效和已关闭的游标,所依赖对象无效时的Lock与Pin的状态。

Pin有两种模式:

· Share (s) : 读一个对象堆

· Exclusive (x) : 修改一个对象堆

无论存贮对象还是瞬时对象,都能被Pinned在Share或Exclusive模式。当修改对象时,进程首先会以Share模式Pin对象,进行错误和安全检查,然后在以Exclusive模式Pin住对象。Pin的解除将会导致相关对象上的易碎锁Break

不同类型的操作所需要的不同类型的lock/pin:

1). 所有的DDL操作都会在需要处理的对象上放一个Exclusive(排他)类型的Lock和Pin(仅仅当执行的时候加上)。

如:重编译,截断表,给对象授权,等等

2). 所有对对象的使用都需要一个null类型lock和shared类型的pin(仅仅当执行的时候加上)。如:使用视图,执行过程,等等。

以上规则,也同样应用于对象所有依赖的对象。如:一个依赖于其他视图的视图,一个依赖于其他包的包。

而对于游标,

例10:以上两点,分明做试验证明。

DDL:create table big_table_2 as select * from big_table

执行以上DDL,通过X$KGLOB观察Big_table的LOCK与PIN状态。同时在另一会话中执行DESC或查询声明。

查询:创建如下过程:

create or replace procedure my_cursor is

msql varchar2(500);

mcur number;

begin

mcur:=dbms_sql.open_cursor;

msql:='select myid from t4 where myid=:x';

dbms_sql.parse(mcur,'select myid from t4 where myid=:x',dbms_sql.native);

dbms_lock.sleep(300);

dbms_sql.close_cursor(mcur);

end;

/

执行以上存储过程,通过X$KGLOB观察MY_CURSOR和游标AA的LOCK与PIN状态,

二、专门查看Library cache中对象的LOCK与PIN的视图(概览)

没有专门的V$视图,查看Library cache lock,可以使用X$kgllk,查看Library cache pins,可以使用X$kglpn。另外,也可以在X$kglob中看到对象的Lock与Pin的信息。

例11:执行一个以前没有执行过的SQL,观察x$kgllk和x$kglpn中的信息。

在X$kglob中也可以查看到Lock与Pin的信息,但X$kglob中没有会话编号。

三、通过以上例子,考虑,如何找到运行中的存储过程和正在打开的游标。