打印本文 打印本文 关闭窗口 关闭窗口
Oracle内存结构:Shared Pool的详细信息
作者:武汉SEO闵涛  文章来源:敏韬网  点击数757  更新时间:2009/4/22 21:58:50  文章录入:mintao  责任编辑:mintao
The Shared Pool在SGA中是SIZE较大的一个部分.有很多DBA没搞明白Shared Pool是用来做什么的,不知道怎么定Shared Pool的合适的SIZE.就随意的将它的SIZE搞得很大.有时候可能是不够大,但更多的时候是在浪费内存空间.而且太大的Shared Pool会影响性能.

块(Chunk):

要更好的理解Shared Pool,得对X$KSMSP表多做点研究.这个表中的每一个记录行对应的是Shared Pool内存中的一个Chunk(块).

SQL> select ksmchcom, ksmchcls, ksmchsiz from x$ksmsp;

KSMCHCOM KSMCHCLS KSMCHSIZ

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

KGL handles recr 496

PL/SQL MPCODE recr 1624

dictionary cach freeabl 4256

free memory free 1088

library cache freeabl 568

library cache recr 584

multiblock rea freeabl 2072

permanent memor perm 1677104

row cache lru recr 48

session param v freeabl 2936

sql area freeabl 2104

sql area recr 1208

上面的是对这个表查询的例子.(对整个表的查询有5726行左右的记录)

在每个Shared Pool Chunk已经分配好之后,代码将语句转化并使其有作用的这一过程实际上就称为一次分配.这个语句可以在X$KSMSP表中的KSMCHCOM字段看到,描述分配的内存Chunk.每一个Chunk都要比它所包含的对象要大,因为每个Chunk都有多出来16字节的头信息用于存储确认Chunk的类型、类别和大小SIZE还有用于Shared Pool管理的链接指针.

内存Chunk主要有四种类别,可以从X$KSMSP表中的KSMCHCLS看到.

free:这种类别的Chunk称为Free Chunk.它不包含有效的对象,可以自由分配.

recr:可重建的Chunk(Recreatable Chunk),这种Chunk有包含对象,而这些对象在必要的时候是可以临时被删除并在有需要的情况下进行重建.一个例子,包含Shared SQL Statements的Chunks就可以重建

freeabl:可释放的Chunk(Freeabl Chunk),这种Chunk也有包含对象,这些对象在一个session的生存期间是经常可用的而在session断掉之后就不可用.这些Chunks可以在session断开之前进行释放,可以部分释放也可以全部释放.Freeable Chunk是不能临时被删除的,因为它是不可重建的.

perm:永久性的内存Chunk(Permanent memory Chunk).它包含的对象是不能被释放的,是永久存在于内存中的.一些大的永久性的内存Chunk内部也包含一定量的free space.可以根据需要释放给shared poo.

select

ksmchcom contents,

count(*) chunks,

sum(decode(ksmchcls, 'recr', ksmchsiz)) recreatable,

sum(decode(ksmchcls, 'freeabl', ksmchsiz)) freeable,

sum(ksmchsiz) total

from

sys.x_$ksmsp

where

inst_id = userenv('Instance') and

ksmchcls not like 'R%'

group by

ksmchcom

KSMCHCOM CHUNKS RECR FREEABL TOTAL

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

KGFF heap 6 1296 2528 3824

KGK contexts 2 2400 2400

KGK heap 2 1136 1136

KGL handles 571 178616 178616

KQLS heap 404 87952 524888 612840

PL/SQL DIANA 274 42168 459504 501672

PL/SQL MPCODE 57 14560 88384 102944

PLS cca hp desc 1 168 168

PLS non-lib hp 1 2104 2104

character set m 5 23504 23504

dictionary cach 108 223872 223872

fixed allocatio 9 360 360

free memory 185 614088

kzull 1 48 48

library cache 1612 268312 356312 624624

multiblock rea 1 2072 2072

permanent memor 1 1677104

reserved stoppe 2 48

row cache lru 24 1168 1168

session param v 8 23488 23488

sql area 983 231080 1303792 1534872

table columns 19 18520 18520

table definiti 2 176 176

上面这个查询可以得到Shared Pool中所有Chunks的类型,类别和大小SIZE等相关信息.上面只列出部分记录.

Free Lists:

Shared Pool中的Free Chunks,于它们的大小为基准被组织成Free Lists或者Buckets.下面的一张表是Bucket号和Free Chunks SIZE的对应关系:


用下面这个脚本可以查询到Chunks数和每个Free List中的Free Space量.

select

decode(sign(ksmchsiz - 80), -1, 0, trunc(1/log(ksmchsiz - 15, 2)) - 5)

bucket,

sum(ksmchsiz) free_space,

count(*) free_chunks,

trunc(avg(ksmchsiz)) average_size,

max(ksmchsiz) biggest

from

sys.x_$ksmsp

where

inst_id = userenv('Instance') and

ksmchcls = 'free'

group by

decode(sign(ksmchsiz - 80), -1, 0, trunc(1/log(ksmchsiz - 15, 2)) - 5)

BUCKET FREE_SPACE FREE_CHUNKS AVERAGE_SIZE BIGGEST

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

0 166344 3872 42 72

1 32208 374 86 96

4 928 1 928 928

6 11784 4 2946 3328

当一个进程需要Shared Pool Memory分配一个Chunk时,它首先会到Free Lists中查找与它所需的SIZE匹配的Chunk.如果跟所需的SIZE没有确切相符的Chunk可以分配则会继续在Free Lists中寻找一个更大的Chunk.如果找到的Chunk有24字节或者更多,则这个Chunk将会被分裂开来使用,将其余的Free Space部分返还到Free Lists中.如果上面的都找不到,则会从一个非空的Free Lists中找一个最小的Chunk给它使用.最后的方式是以LRU机制对Free Lists进行描述

Free Lists的描述,管理和Chunk的分配都是在Shared Pool Lathes的保护下进行的.如果Shared Pool包含有大量的小的Free Chunks时,在对这个特殊的Free Lists进行描述时,Shared Pool Lathes将会被占有比较长的一段时间.实际上,经常出现的Shared Pool Lathes的竞争和等待就是因为包含了大量的小的Free Chunks.所以增加Shared Pool 的SIZE并不能减少Shared Pool Lathes Contention而且还会使得这个竞争更加严重,这就是前面提到的将Shared Pool的SIZE设为很大并不一定会提高性能原因.

LRU Lists:

如果一个进程没办法从Shared Pool Free Lists中获得一个Free Chunk,则它会从Shared Pool中删除一个包含有Recreatable对象的Chunks来释放足够大的Chunks满足自己的使用.

Recreatable Chunks有两个种类:一种是Pinned在内存中的,一种是没有Pinned在内存中的.Pinned在内存中的Chunks跟用DBMS_SHARED_POOL.KEEP执行来KEEP在Shared Pool中是不一样的. DBMS_SHARED_POOL.KEEP是需要DBA来干预执行的,并且只能放在library cache中.而Pinned Chunks是自动执行的,它在Chunks包含正在使用的对象时就会自动被pinned在Shared Pool中.Pinned Recreatable Chunks是不能释放空间的,而Unpinned Recreatable Chunks是可以释放出来的.

在Shared Pool中,Unpinned Chunks被组织成两个Lists,它们都是以LRU机制来排列的.分别被称为临时的LRU List和循环的LRU List. Chunks在Unpinned时放在MRU(most recently used)的最后面,在它们pinned时将会从这个MRU List中删除.




打印本文 打印本文 关闭窗口 关闭窗口