300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Shared pool内存块组成结构及4031错误原因分析

Shared pool内存块组成结构及4031错误原因分析

时间:2021-09-27 07:30:56

相关推荐

Shared pool内存块组成结构及4031错误原因分析

这篇文章是参考甲骨论老相老师的教学视频所做的学习笔记:

/v_show/id_XMzkyMDQ4MzUy.html

之前提到Shared pool的作用:

Shared pool是用来缓存sql语句以及sql的执行计划的,

而share pool包含3主要大部分(还有其他很多部分)

分别是library cache, rowcache和 free memory

首先强调一句: 我们可以手动设置Shared pool的大小, 但是并不能制定shared pool里面 Free/Library Cache/rowcache 等各部分的大小的.

1.现在分析下Free 空间的内存空间:

其实可以参考下图:

如上图, 其实Free空间并不是1个大的内存块, 而是由许多个有固定顺序内存链(chain)组成的,其中每1条chain都有起始位置和终点,在每1条chain上都挂着许多大小相近的内存块(chunk).例如上面第一条chain挂着chunk大小大概是每个4k,中间是每个chunk 8k,最下面果条每个12k啦~

但是了解过数据结构的都知道, 内存链chain在物理上是不存在的, 而每个chunk也不是物理上相邻的, 每1条链实际上是分别在内存里各个位置的若干个chunk组成. 第1个chunk的头部放着这条chain的起始位置,也就是这条chain的内存位置,然后尾部放着1个指针,指向下1个chunk的内存地址.. 直到之后1个chunk尾部不放指针. 这样就组成了1条内存链chunk

但是逻辑上可以参照上图理解啦~

2. 现在要解析一条sql语句, 需要占用free空间.

假如,现在要解析一条新的语句, 需要额外的10k空间, 那么server process会怎么找出这10k的空间呢,

如下图, 首先下图中8k那第条链,它的chunk都是8k - 12k的, 所以server process会找这一条链遍历,假如它找到一个chunk是11k了,那么它会将这个chunk分成10k 和 1k两个部分, 其中10k 那个部分作为1个新的chunk放到 属于library cache的chain中, 就相当于把这个chunk从free空间移到library cache了(当然不是物理上移动这个chunk,只需修改相应的chunk尾部指针). 而剩余的1k那个部分,也不能留在8k这一条链了, 会比移到存放1k左右chunk的那条链.

由这过程可以得出,这种sql语句解析动作很可能会产生一些小的内存碎片(1k那个部分), 实际上这种sql动作就是所谓的硬解析,而软解析只需在library cache查找出缓存的执行计划,是不需要去征用Free memory的.

关于硬解析和软解析可以参考:http://nvd11./blog/static/2000183182642475/

3. 4031错误的产生

所以说硬解析会产生内存碎片, 而一个服务器在进行大量的硬解析是则在shared pool产生大量的碎片, 这时即使Free Memory空间内还有不少的空间, 但里面很可能都是小chunk(碎片), 而没有大的chunk了.

这时,若数据库又接受到1个很复杂的sql语句要进行硬解析, 需要在free空间找一些大的chunk,但是free空间内只有碎片..这样这个硬解析会失败,而oracle则可能会报1这种很经典的错误,就是4031错误.

所以4031错误的产生原因有两个:

1. 数据库大量的硬解析.

2. 大量硬解析产生大量的碎片,而这时又要执行1个复杂的硬解析动作.

4. 内存链(chain)的结构.

其实内存链的结构可以参考下图啦:

上图是由3个chunk组成的内存链 chain.

可以看出内存chain内的chunk在物理上并不一定是相邻的,而且也不一定是在物理上按顺序排列的.

如上图, 物理上排中间那个chunk才是chain中的第一个chunk, 因为没有指针指向它的头部地址, 然后它的尾部指向第2个chain..

而第3个chain因为他的尾部是空指针,所以他是这个内存链的最后1个chunk.

所以当加入和删除chunk时只需改变相应chunk的指针指向就可以了

其实这是1个经典的链表结构啦.

5. 内存链(chain)的一些特性

所以chain有两个特点:

1. 由多个chunk串联组成.

2. 可以遍历(根据指针去遍历啦)

而Oracle 会 让一种叫Latch的锁去保护chain的结构.

6. Server process会写一些什么内容进入Chunk呢.

我们由上面的图解可知. 那些chunk在free空间里面是空的, 搬到library cache里面会被写上内容了.

下面就分析到底写了什么数据进去..

我们知道library cache是用来存放sql语句和其执行计划的, 那么里面数据肯定与之相关了:

首先

sql语句会被转换成ASCII码, 然后经过一系列若干步算法, 会转会成一串数字:

而最终这串数子,包换1个链的编码,加入这个号码是5.

当然如果是硬解析,则server process还会解析这个sql,并得出执行计划写到这个chunk上.

如下图

7. 软解析和硬解析

由上图得知, 每一条sql语句总会经过运算得到1个chain号码.

1.所以当某条sql语句进入shared pool时. 系统会首先计算出对应这个sql的chain号码(上图动作1)

2. 然后server process会在library cache对应号码的chain上遍历,寻找有无缓存了这条sql的执行计划的chunk.

3. 如果找不到,则会在Free 空空间搬1个新的chunk挂到 library cache的对应chain上,别解析sql语句得出执行计划写入这个chunk中.这就是硬解析(上图动作2)

4.这时这个session或另一个session 传送来另1个相同的sql语句. 经过运算得出相同的chain号.(动作1)

5.server process还是会在对应chain上遍历,因为之前硬解析过一次,所以这次找到缓存执行计划的chunk了,就直接将该执行机会拿出来用了,这就是软解析,不需执行动作2

8. library cache里面的chain管理.

由上面分析得知, library cache里与free空间不同,并不是按chunk的大小空间去组成1条chain的,而是按硬解析后sql的运算出来的chain号码来组成1条chain的. 这样更加方便server process去查找缓存

跟free空间一样, library cache同样有 Library cache latch去维护chain的结构.

9.Rowcache(字典缓存)以用样类似的方式去管理

也是说同样是chain结构. 而且居然rowcache latch了

10.一些动态数据字典:

10.1 x$ksmsp 这张表 存放了shared pool的每1个chunk的信息.

x$ksmsp的detail信息可以参考这里.

执行select count(1) from x$ksmsp 能查看shared pool chunk总数

这时我们执行一条之前从未执行过的sql语句(会发生硬解析)

这时,再去查看shared pool的chunk数量,发现增加了,也代表硬解析产生了碎片..

也可以理解出, shared pool里面的chunk数量越多(大小固定之下), 碎片就越严重.

加入我们每10分钟执行一次查询, 那么10分钟后的chunk数量 - 10分钟前的chunk数量就是这10分钟增加的chunk数量

随着系统运行,应该没10分钟增加的chunk数量应该会越來越少(缓存数据增多,软解析多).

若某一段时间增加了大量chunk数量,通常代表这段时间发生大量的硬解析.产生了大量碎片.

不过通常我们会利用 v$sysstat 来查看硬解析数量.

11, 清空shared pool缓存数据.

Alter system flush shared pool;

这条命令用于清空shared pool所有的缓存数据!

通常执行这条命令后, 4031错误就会消失, 但是接下来就会发生大量硬解析,因为缓存都被清空啦.

所以对于4031错误来讲,执行这条命令只是1个治标不治本的方法... 治本方法通常是加大shared pool的大小,也就是加内存啦.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。