Oracle硬核之library cache 内存结构剖析

网友投稿 1251 2022-10-14

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

Oracle硬核之library cache 内存结构剖析

library cache 内存结构是ORACLE极为核心也是极为复杂的一部分,日常运维遇到与library cache 相关的性能问题或故障也屡见不鲜,理解 library cache 内存结构必不可少,这次以library cacke lock、pin等待事件为题,结合相关案例对 library cache 内存结构做一次深入剖析。

文章结构主要包括如下4部分:

1、library cache内存结构了解

----了解library cache存放的内容,通过图形分析library cache内存结构,最后通过dump library

cache进行更直观地了解library cache内存结构

2、library cache lock/pin解释

----了解等待事件的意思

3、实验模拟分析

----追踪library cache lock 及 pin的一个完整获取及释放的过程,再模拟出等待事件,以及利用

systemstate dump对等待事件的分析

4、案例分析

----通过案例进行探讨这类等待事件的分析方法

一、library  cache内存结构了解

(1)存放的内容

从官方说明及我们查询v$librarycache实图记录的内容可知,library cache主要存放shared curosr(SQL)和PLSQL对象(function,procedure,trigger)的信息,以及这些对象所依赖的table,index,view等对象的信息。

(2)内存结构

以上这图可看出library cache大体是由 hash bucket以及对应的library object handle双向链组建成的框架。

大体框架我们知道后,放大一点里面的构造,从以上图又可知道,一个latch管理多个hash bucket,然后一个hash bucket里的library object handle上的访问存在三种队列信息,包括owners\converters\waiters队列,它们存放着持有该handle资源、等待该handle资源的队列信息,其中converers理解为由等待变换成持有这个过程的队列信息。

library cache基本框架知道后,当新增一个对象插入到library cache双向链中,从以上图就可知道双向链的结构变化过程,原理就是通过0x开头的一串数字唯一标识handle本身的位置,另外handle还存放它前、后handle的指针标识,这样就实现双向链的无缝衔接。

如果继续放大handle里的内容就如上图所示,我们知道handle有它0x开头的一串数字唯一标识,这样就可以唯一指向handle的dependency table(依赖对象)、child table(子对象)、authorization table(对象授权信息)、type(对象类型)、status flags(状态标识)、Data Blocks(指向数据存放的dataheap),其实上图是前辈们根据Library cache里存放的内容所绘制而成以方便理解它里面的结构,如果想更真实、直观地理解上图可通过dump出library cache里的内容以作梳理的。

(3)dump library cache

以上是library cache dump级别的官方说明,然后我们来做一次小测试如下:

----执行一条测试SQL

---dump library cache

---测试SQL在library cache里存放的信息

从以上三张图可知道,测试SQL被解释后存放在library cache里的bucket号37147里的library object handle上,handle地址为 0x8bbfce10,从这个handle地址的内容了解到以下内容:

1、ObjectName 对应SQL语句文本

2、Namespace 为SQL AREA ,Type为CURSOR

3、ExecutionCount 为3说明这条SQL被记录到执行了三次

4、Dependencies count=2 表明这个SQL有两个依赖对象,一个是用户LMJ,另一个是用户LMJ下的表TEST1

--Dependency num=0 第一个依赖对象的handle地址=0x91add7e0 TYPE=NONE(255) Parent=LMJ

--Dependency num=1 第二个依赖对象的handle地址=0x8b834628 TYPE=TABLE(02) Parent=LMJ.TEST1

5、DataBlocks 指向数据存放的data heap,我们的dump对应两个heap,一个heap 0 Pointer=0x8c73e150 指针指向 Parent Cursor,另一个heap 6 Pointer=0x8bd3e550 指针指向 Child Cursor去掉一些不关心的信息,进一步看Dependencies的内容,从以下部分更清晰的知道SQL有两个依赖对象的内容信息:

另外从dump信息也可知道SQL执行的效率信息: CPU TIME\ Elapsed time等

二、library  cache类等待事件

上部分内容我们可理解library cache内存结构结构图,知道library cache存放内容,懂得解读 library cache dump的trace,那么接下来还需要理解library cache类等待事件的含义,这里我们解读官方对library cache lock/pin做的解释。

---"library cache lock" Reference Note

---"library cache pin" Reference Note

pin是维护library object handle下对应heaps的并发访问的

三、实验模拟分析

下面进行一个实验模拟,追踪library cache lock 及 pin的一个完整获取及释放的过程,再模拟出等待事件,以及利用systemstate dump对等待事件的分析。

1、创建存储过程P_ TEST,并查询出其handle address SQL>

2、当前等待事件正常

3、连接一个会话SID:39,SPID:9685

4、利用DTrace跟踪会话39的SPID:9685

5、会话39执行p_test存储过程

SQL> exec p_test

…进行sleep等待

6、分析SPID:9685的DTrace跟踪内容

bash-3.2# ./lib.d 9685

dtrace: script './lib.d' matched 3 probes、

== pin mode

col PROGRAM for a30

col username for a10

col machine for a18

col event for a20

select a.sid,a.sql_id,a.event,a.username,a.machine,a.program,a.blocking_session,a.BLOCKING_INSTANCE,

b.KGLPNMOD pin_mode, b.KGLPNREQ

from v$session a,x$kglpn b

where a.saddr=b.kglpnuse and b.kglpnhdl like '%00000000EC7DA508%'

/

小结:

根据DTrace的过程可以得出,会话39执行存储过程p_test,其中在p_test的handle address上的请求过程为:

1、先请求share 模式的library cache lock,请求得到后,shared模式降至NULL模式,即我们查出显示 LOCK_MODE=1

2、后继续请求share模式的library cache pin,请求得到后此会话正常运行p_test,但会话未运行结束所以share模式的library cache pin未释放,即我们查询p_test的handle address显示PIN_MODE=2

3、即最后结果是,会话39在library cache中p_test的handle address持有NULL模式的library cache lock和share模式的library cache pin。

7、连接另一个会话SID:41,SPID:9702

8、利用DTrace跟踪会话41的SPID:9702

9、会话41删除p_test存储过程

SQL> drop procedure p_test;

…处于waiting等待

10、查询等待事件,library  cache  pin出现

11、分析SPID:9702的DTrace跟踪内容

分析小结:

根据DTrace的过程可以得出,会话41删除存储过程p_test,其中在p_test的handle address上的请求过程为:

1、首先申请Exclusive模式的library cache lock并已得到且不释放,从x$kgllk查询出LOCK_MODE=3得以证明

2、然后申请Exclusive模式的library cache pin后处于等待状态,等待事件表现为library cache pin,从x$kglpn查询出KGLPNREQ=3得以证明

3、即最后结果是,会话41在library cache中p_test的handle address持有Exclusive模式的library cache lock,并申请 Exclusive模式的library cache pin处于等待状态。

12、systemstate  dum分析library  cache  pin

从实验模拟过程可得出阻塞关系:

SID:39 (阻塞源)<— SID:41(被阻塞者)

39持有NULL模式lock及share模式pin <—41持有Exclusive模式lock,等待Exclusive模式pin抓取systemstate dump进行深入分析

会话39的内容:

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

会话41的内容:

分析结果:

1、会话39持有p_test对应handle address上的null模式的Library cache lock种share模式的library cache pin

2、会话41在library cache中p_test的handle address持有Exclusive模式的library cache lock,并申请  Exclusive模式的library cache pin处于等待状态

四、案例分析

1、问题描述

2017年8月9日15:40左右某系统三个节点出现大量异常等待事件library cache pin,业务缓慢受堵,就此问题进行分析。

2、故障现象

分析小结:

08月9日 15:46:08开始,数据库突然出现大量的异常等待事件library cache pin并不断累积。

1)library cache pin等待的对象

分析hanganalyze 文件XXXX2_diag_178650.trc,发现如下:

发现等待的规律:

节点1的library cache pin 的对象地址都是在“0x116e454df0”

上节点2的library cache pin 的对象地址都是在“0x11ce403120”

上节点3的library cache pin 的对象地址都是在“0x11cf16bcb0”

根据x$kglob查询出对象名:

节点1查询x$kglob得出此对象地址为XXXX.XX_PUBLIC

节点2查询x$kglob得出此对象地址为XXXX.XX_PUBLIC

节点3查询x$kglob得出此对象地址为XXXX.XX_PUBLIC

官方说明:

Mode  is  the  mode  in  which  the  pin  is  wanted.  This  is  a  number  thus:

2 - Share mod

3 - Exclusive mode

分析library cache pin等待事件的p3(申请的锁模式),发现它们的共同点都是2,即这些被阻塞的会话想在XXXX.XX_PUBLIC申请shared 共享模式的锁,但被阻塞,由此可见有会话在XXXX.XX_PUBLIC上申请X排它模式的锁或持有X排它模式的锁未释放的情况,导致后面的会话无法申请shared共享锁而只能等待。

分析小结:

从hanganalyze分析,清楚的得出节点1、2、3的library cache pin等待事件都是在等待对象XXXX.XX_PUBLIC上,它们想申请shared 模式的锁但被阻塞。

2)library cache pin根因

根据前面分析怀疑有会话申请或持有XXXX.NEW_BUSI_PUBLIC的X排它模式的锁,导致后面申请share共享模式锁的会话被阻塞

所以继续查询hanganalyze trace文件,发现节点2的会话'session si:6199,os id:18761'发起对XX_PUBLIC的COMPILE编译的动作,信息如下:

至此,问题根因已清楚明了,原因是节点2 的会话6199对包XXXX.XX_PUBLIC进行编译申请X排它模式的锁,而导致后面申请XXXX.XX_PUBLIC share共享模式锁的会话被阻塞,导致library cache pin等待事件的出现。

节点2 的会话6199的信息如下,是应用机器发起的对XXXX.XX_PUBLIC进行做编译的DDL操作。

3)分析小结

(1) 15:46:08 节点2的会话6199对应的应用机器发起了对XXXX.XX_PUBLIC编译的DDL操作,导致从15:46:08 开始,节点1、2、3的会话无法共享访问XXXX.XX_PUBLIC而出现library cache pin等待事件。

(2)此故障为典型的Library cache pin案例,是在业务高峰期时对包XXXX.XX_PUBLIC编译的DDL操作导致,oracle不建议在业务高峰期对访问频繁的对象进行编译或其它DDL操作,因为这些操作很有可能会导致shared pool中lath的争用,从而导致大量异常事件出现而影响数据库性能。

===END===

本期作者

本期作者 | 刘大师:从事oracle工作多年,OCM,精通Oracle数据库故障分析处理、Oracle EXADATA一体机运维。

上一篇:Grep 高效用法实战总结 - 运维笔记
下一篇:查看数据库占用磁盘空间的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~