读后感:oracle性能调整 Shared pool深入分析及性能调整

今天在网上读了文章:oracle性能调整 Shared pool深入分析及性能调整。

在这篇文章中,对以下问题做了比较深刻的解释:

1.为什么程序中引用了绑定变量可以加快效率

2.ORA-04031的成因

[@more@]

1.为什么程序中引用了绑定变量可以加快效率

oracle 对sql语句的解析实际上生成执行计划。在生成执行计划时是需要消耗资源的。为了实现这一过程,oracle实际上对sql语句进行了概括与抽象。将sql语句分成静态与动态两部分。静态部分包括oracle的关键字,如select,from等,以及表名,列名等。而动态部分实际上就是数据。静态部分是有限的小部分,而数据是无限的。也就是说,只要结构都一样,产生的执行计划也一样。如果使用了绑定变量,就可以实现这个目的。

2.ORA-04031的成因

shard pool size由内存块组成,这些内存块被称为chunk.这些chunk有4种状态。分别为:

注:可以通过观察x$ksmsp表的ksmchcls列进行观察。

2.1 free-为分配的。根据需求可能进行dictionary cache,也有可能进入library cache。

2.2recr-指recreatable. 这种chunk中的对象可以在需要时临时被移走。并且在需要时重建。在进行解析时,当需要分配内存块时,当free的chunk没有合适大小的内存块时,oracle就从这一部分进行分配。

2.3freeabl--这种chunk中的对象都是曾经被session使用过的,随后会被完全或部分释放,这种类型的chunk是无法临时从内存中移走的。否则就无法重建。

2.4perm--永久对象。

用命令:

alter session set events 'immediate trace name heapdump level 2';

在share pool size中,可用的chunk我们叫bucket。它其实是将free的chunk串起来,相当于free list。供内存分配。

观察dump文件,搜索free list,我们可以看到这样的部分:

..................................

Bucket 222 size=2284
Bucket 223 size=2348
Bucket 224 size=2412
Bucket 225 size=2476
Bucket 226 size=2540
Bucket 227 size=2604

这表示有总共有227个bucket。

有了以上的背景知识后,可以看具体的ORA-04031的成因:

注:以下为引用部分:

当一个进程需要shared pool里的一个chunk时,假设当前需要21个单位的空间,则该进程首先到符合所需空间大小的bucket(这里就是bucket 2)上去扫描,以找到一个尺寸最合适的chunk,扫描持续到bucket的最末端,直到找到完全符合尺寸的chunk为止。如果找到的chunk的尺寸比需要的尺寸要大,则该chunk就会被拆分成两个chunk,一个chunk被用来存放数据,而另外一个则成为free类型的chunk,并被挂到当前该bucket上,也就是bucket 2上。然而,如果该bucket上不含有任何需要尺寸的chunk,那么就从下一个非空的bucket上(这里就是bucket 3)获得一个最小的chunk.如果在剩下的所有bucket上都找不到可用的chunk,则需要扫描已经使用的recreatable类型的chunk 链表,从该链表上释放一部分的chunk出来,因为只有recreatable类型的chunk才是可以被临时移出内存的。当某个chunk正在被使用时(可能是用户正在使用,也可能是使用了dbms_shared_pool包将对象钉在shared pool里),该chunk是不能被移出内存的。比如某个SQL语句正在执行,那么该SQL语句所对应的游标对象是不能被移出内存的,该SQL语句所引用的表、索引等对象所占用的chunk也是不能被移出内存的。当shared pool中无法找到足够大小的所需内存时,报ORA-4031错。当出现4031错的时候,你查询v$sgastat里可用的shared pool空间时,可能会发现name为“free memory”的可用内存还足够大,但是为何还是会报4031错呢?事实上,在oracle发出4031错之前,已经释放了不少recreatable类型的chunk了,因此会产生不少可用内存。但是这些可用chunk中,没有一个chunk是能够以连续的物理内存提供所需要的内存空间的,从而才会发出 4031的错。