签到成功

知道了

CNDBA社区CNDBA社区

Oracle Library Cache Lock 解决思路

2016-11-25 15:42 2526 0 原创 Oracle 故障处理
作者: dave

 

一.  Library Cache Lock

 

  

 

Library cacheHandle 里保存了lock 和 pin 的信息。而且在Library cache handle 和child cursor 上都有lock 和pin。它们称为library cache lock和library cache pin。

 

Library cachelock/pin是用来控制对librarycache object的并发访问的。Lock管理并发,pin管理一致性,lock是针对于librarycache handle, pin是针对于heap

       当我们想要访问某个library cache object,我们首先要获得这个指向这个object的handle的lock,获得这个lock之后我们就需要pin住指向这个object的heap。

 

       当我们对包,存储过程,函数,视图进行编译的时候,Oracle就会在这些对象的handle上面首先获得一个library cache lock,然后再在这些对象的heap上获得pin,这样就能保证在编译的时候其它进程不会来更改这些对象的定义,或者将对象删除。

 

       当一个sessionSQL语句进行硬解析的时候这个session就必须获得librarycache lock,这样其他session就不能够访问或者更改这个SQL所引用的对象。如果这个等待事件花了很长时间,通常表明共享池太小(由于共享池太小,需要搜索free的chunk,或者将某些可以被移出的object page out,这样要花很长时间),当然了,也有可能另外的session正在对object进行修改(比如split 分区),而当前session需要引用那个table,那么这种情况下我们必须等另外的session进行完毕。

 

Library Cache lock3中模式:

       (1)Share(S):      当读取一个library cache object的时候获得

       (2)Exclusive(X):  当创建/修改一个library cache object的时候获得

       (3)Null(N):     用来确保对象依赖性

 

       比如一个进程想要编译某个视图,那么就会获得一个共享锁,如果我们要create/drop/alter某个对象,那么就会获得exclusive lock。Null锁非常特殊,我们在任何可以执行的对象(cursor,function)上面都拥有NULL锁,我们可以随时打破这个NULL锁,当这个NULL锁被打破了,就表示这个对象被更改了,需要从新编译。

       NULL锁主要的目的就是标记某个对象是否有效。比如一个SQL语句在解析的时候获得了NULL 锁,如果这个SQL的对象一直在共享池中,那么这个NULL锁就会一直存在下去,当这个SQL语句所引用的表被修改之后,这个NULL锁就被打破了,因为修改这个SQL语句的时候会获得Exclusive 锁,由于NULL锁被打破了,下次执行这个SQL的时候就需要从新编译。

 

Library Cache pin2种模式:

       (1)Share(S):      读取object heaphttp://www.cndba.cn/dave/article/455

       (2)Exclusive(X): 修改object heap

 

       当某个session想要读取object heap,就需要获得一个共享模式的pin,当某个session想要修改object heap,就需要获得排他的pin。当然了在获得pin之前必须获得lock。

 

       在Oracle10gR2中,library cache pin被library cache mutex 所取代。

 

Library cache latch用来控制对library cache object的并发访问。前面已经提到,我们要访问library cacheobject之前必须获得librarycache lock, lock不是一个原子操作(原子操作就是在操作程中不会被打破的操作,很明显这里的lock可以被打破), Oracle为了保护这个lock,引入了library cache latch机制,也就是说在获得library cachelock之前,需要先获得library cache latch,当获得library cache lock之后就释放librarycache latch

 

http://www.cndba.cn/dave/article/455

       如果某个librarycache object没有在内存中,那么这个lock就不能被获取,这个时候需要获得一个library cache load lock latch,然后再获取一个librarycache load lock,load lock获得之后就释放library cache load lock latch

 

       librarycache latch受隐含参数_KGL_LATCH_COUNT的控制,默认值为大于等于系统中CPU个数的最小素数,但是Oracle对其有一个硬性限制,该参数不能大于67。

       注意:我们去查询_kgl_latch_count有时候显示为0,这是一个bug。

 

Oracle利用下面算法来确定library cache object handle是由哪个子latch来保护的:

       latch#= mod(bucket#, #latches)

 

       也就是说用哪个子latch去保护某个handle是根据那个handle所在的bucket号,以及总共有多少个子latch来进行hash运算得到的。

 

 http://www.cndba.cn/dave/article/455

MOS 的文档【122793.1里说导致librarycache lock通常有2种原因:

 

(1)A DML operation that is hangingbecause the table which is accessed is currently undergoing changes (ALTERTABLE). This may take quite a long time depending on the size of the table andthe type of the modification (e.g. ALTER TABLE x MODIFY (col1 CHAR(200) on atable with thousands of records)

In this case,V$LOCK will show that the session doing the 'ALTER TABLE' with an exclusive DMLenqueue lock on the table object (LMODE=6, TYPE=TM where ID1 is the OBJECT_IDof the table). The waiting session however does not show up in V$LOCK yet so inan environment with a lot of concurrent sessions the V$LOCK information will beinsufficient to track down the culprit blocking your operation.http://www.cndba.cn/dave/article/455

 

(2)The compilation of package willhang on Library Cache Lock and Library Cache Pin if any users are executing aprocedure/function defined in the same package.

 

 

更多内容参考:

OracleLibrary cache 内部机制 说明

http://blog.csdn.net/tianlesoftware/article/details/6629869

 

OracleLibrary Cache 的lock 与 pin 说明

http://blog.csdn.net/tianlesoftware/article/details/6641440

 http://www.cndba.cn/dave/article/455

OracleNamespace 说明

http://blog.csdn.net/tianlesoftware/article/details/6624122http://www.cndba.cn/dave/article/455

 

一次librarycache pin故障的解决过程

http://blog.csdn.net/tianlesoftware/article/details/6638899

 

 

.  处理Library cache lock

 

2.1 使用hanganalyze  + systemstat 分析

 

Systemstat 事件包含每个oracle 进程的详细信息。当操作hang住时,可以新开一个窗口,使用该事件,捕获相关信息。

 

Systemdump 级别说明:

 

LEVEL参数:

10   Dump all processes (IGN state)

5    Level 4 + Dump all processes involved in wait chains (NLEAF state)

4 Level 3 + Dump leaf nodes (blockers) in wait chains(LEAF,LEAF_NW,IGN_DMP state)

3    Level 2 + Dump only processes thought to be in a hang (IN_HANG state)

1-2  Only HANGANALYZE output, no process dump at all

 

level 266= SYSTEM STATE (level=10, withshort stacks) =  level 10 + short stacks

level 266 在level 10的基础上包含了进程的short stacks信息

 

 

Oracle 9.2.0.1 之后,执行如下脚本:

$sqlplus '/ as sysdba'
oradebugs etmypid
oradebug unlimit
oradebug dump systemstate 266

oradebug tracefile_name

 

systemstat 226级别在9.2.0.6 之前不可用,所以在之前的版本可以使用如下命令:

alter session set max_dump_file_size=unlimited;
alter session set events 'immediate trace name systemstate level 10'

 

 

先执行hanganalyze,如下:

SQL> oradebug setmypid

SQL>oredebug unlimit

SQL> oradebug setinst all

SQL> oradebug -g def hanganalyze 3;

SQL>oradebug tracefile_name

 http://www.cndba.cn/dave/article/455

如下文件里其他session都被1169的阻塞:

State of ALL nodes

([nodenum]/cnode/sid/sess_srno/session/ospid/state/[adjlist]):

[1001]/1/1002/9/c00000063d7aff78/9720/NLEAF/[1169]

[1159]/1/1160/51635/c00000063d8dfc68/19539/NLEAF/[1169]

[1160]/1/1161/15627/c000000631959658/8818/NLEAF/[1169]

[1162]/1/1163/27931/c0000006398d7810/20170/NLEAF/[1169]

[1165]/1/1166/4003/c0000006358f4d58/22069/NLEAF/[1169]

[1166]/1/1167/45511/c0000006398d4868/15674/NLEAF/[1169]

[1167]/1/1168/46253/c00000063d8d9d18/29492/NLEAF/[1169]

[1169]/1/1170/9233/c0000006358f1db0/9434/LEAF_NW/

[1170]/1/1171/43901/c0000006398d18c0/13246/NLEAF/[1169]

[1171]/1/1172/53701/c00000063d8d6d70/13794/NLEAF/[1169]

[1172]/1/1173/23737/c000000631950760/25188/NLEAF/[1169]

[1173]/1/1174/28801/c0000006358eee08/24770/NLEAF/[1169]

[1175]/1/1176/25017/c00000063d8d3dc8/18795/NLEAF/[1169]

[1177]/1/1178/3/c0000006358ebe60/10170/NLEAF/[1169]

 

这里sess_srno 是v$session 中的serial#.

Ospid 是系统进程号。

 

找到了sid和serial# 就可以查看对应session 的信息,是什么操作。 如果session 没有sql_id, 那么可以进一步使用oradebug systemdump 对应的进程。 来查看信息。

 

SYS@dave2(db2)> oradebug setospid 9434

Oracle pid: 18, Unix processpid: 27028, image: oracledave2@db2

SYS@dave2(db2)> oradebug unlimit

Statement processed.

SYS@dave2(db2)> oradebug dump systemstate 10

Statement processed.

SYS@dave2(db2)> oradebug TRACEFILE_NAME

/u01/app/oracle/admin/dave2/udump/dave2_ora_27028.trc

 

SYS@dave2(db2)> oradebug close_trace

Statement processed.

 

然后使用awk来分析systemdump 的trace:

Oracle 使用ass.awk 工具查看system state dump 说明

http://blog.csdn.net/tianlesoftware/article/details/7237729

 

这里也可以直接用systemdump 查看所有的进程信息。

 

 

http://www.cndba.cn/dave/article/455

2.2 查看X$KGLLK

The X$KGLLK table (accessibleonly as SYS/INTERNAL) contains all the library object locks (both held &requested) for all sessions and is more complete than the V$LOCK view althoughthe column names don't always reveal their meaning.

--X$KGLLK 表只能被SYS/INTERNAL用户访问,其包含所有library object locks的信息(heldrequested)。

 

 

--查看等待事件为librarycache locksession session address (SADDR):

 

SQL>select sid,saddr from v$session where event='library cache lock';
SID SADDR
---------- --------
16 572ed244

--x$kgllk查看具体的锁信息:

select kgllkhdl Handle, kgllkreq Request,kglnaobj Object

  from x$kgllk

 where kgllkses = '572ed244'

   and kgllkreq > 0;



HANDLE      REQUEST   OBJECT
-------- ---------- -------------------
62d064dc          2EMPLOYEES

 

 

KGLLKREQ: This will show you the library cache lock requested by this session(KGLLKREQ > 0)

KGLNAOBJ:contains the first 80 characters of the name of the object.

KGLLKHDL:corresponds with the 'handle address' of the object

 

 

--然后根据KGLLKHDLX$KGLLK查看KGLLKMOD > 0session,其正在持有该锁:

 

select kgllkses saddr, kgllkhdl handle,kgllkmod mod, kglnaobj object

  from x$kgllk lock_a

 where kgllkmod > 0

   andexists (select lock_b.kgllkhdl

          from x$kgllk lock_b

         where kgllkses = '572ed244'/* blocked session*/

           and lock_a.kgllkhdl =lock_b.kgllkhdl

           and kgllkreq > 0);

 


SADDR    HANDLE         MOD    OBJECT
-------- ----------- ------- --------

572eac94  62d064dc      3      EMPLOYEEShttp://www.cndba.cn/dave/article/455

 

 

 

--查看所有blockedsession

selectsid, username,terminal, program

  from v$session

 where saddr in

       (select kgllkses

          from x$kgllk lock_a

         where kgllkreq > 0

           andexists (select lock_b.kgllkhdl

                  from x$kgllk lock_b

                 where kgllkses = '572eac94'/* blocking session*/

                   and lock_a.kgllkhdl =lock_b.kgllkhdl

                   and kgllkreq = 0));

 

--查看所有持有librarycache pin 或者locksession 在做什么:

 

SELECT s.sid, kglpnmod"Mode",kglpnreq "Req", SPID "OS Process"

  FROM v$session_wait w,x$kglpn p, v$session s, v$process o

 WHERE p.kglpnuse =s.saddr

   AND kglpnhdl = w.p1raw

   and w.event like'%library cache %'

   and s.paddr = o.addr

 

 

2.3 处理问题

一般来说,使用2.1 或者2.2 的方法都可以找到library cache lock的根源,确定是哪个session 导致的,如我们上面的hanganalyze中,是1169的session。 我们只需要kill 掉这个session,其他的问题就会自动解决了。

 

先在DB级别kill session,如果kill 不了,在os 级别kill。

 

alter systemkill session '1170,9233';

 

注意在os 级别kill 之前,先用ps 命令查看一下该进程,如果是DB 进程,不可随意kill,否则会导致系统crash。

 

ps ­–ef|grep 9434

kill -9 9434

 

 http://www.cndba.cn/dave/article/455

参考:

How to Find which Session is Holding a ParticularLibrary Cache Lock [ID 122793.1]

 

 

 

 

 

-------------------------------------------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

Skype: tianlesoftware

QQ:              tianlesoftware@gmail.com

Email:   tianlesoftware@gmail.com

Blog:     http://www.tianlesoftware.com

Weibo: http://weibo.com/tianlesoftware

Twitter: http://twitter.com/tianlesoftware

Facebook: http://www.facebook.com/tianlesoftware

Linkedin: http://cn.linkedin.com/in/tianlesoftware

 

 

-------加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请----

DBA1 群:62697716(满);   DBA2 群:62697977(满)  DBA3 群:62697850(满)  

DBA 超级群:63306533(满);  DBA4 群:83829929   DBA5群: 142216823

DBA6 群:158654907    DBA7 群:172855474   DBA总群:104207940

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2297
    原创
  • 3
    翻译
  • 754
    转载
  • 201
    评论
  • 访问:11061167次
  • 积分:4652
  • 等级:核心会员
  • 排名:第1名
精华文章
    热门文章
      Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

      AI QQ群