从物理角度上看Oracle shared pool ,它是由多个内存块组成。这里的内存块相当于数据文件中的数据块,是最小的分配单位。这个最小分配单位称为chunk ,它里面的内存字节是连续的。但每个chunk 的大小是不固定的。
shared pool 的内存分配由heap (堆)来实现。heap 的个数由隐含参数”_kghdsidx_count “ 来决定。
每个heap 下又有多个sub-heap ,他们之间的关系称为高级堆和副堆。他们的结构大致相同。
heap 由一个或多个extent 和heap header 组成,而extent 又由若干个chunk 和extent header 组成,而chunk 由chunk header 和chunk body 组成。
每个extent 的体积是若干个granule (有文档说是一个,但dump 出来看不只一个)。granule 是shared pool 逻辑角度上的组成单位。这个granule 是固定值,不同的SGA 下大小不同,如10g 中SGA_MAX_SIZE<=1024MB ,则granule 的值为4MB ;SGA_MAX_SIZE>1024MB ,则granule 的值为16MB 。可以通过v$sgainfo 去查证。
从视图 select ksmchcls, count (*) from x$ksmsp group by ksmchcls; 中可以看到shared pool 的每个chunk 的类型。
KSMCHCLS |
COUNT(*) |
free |
3299 |
freeabl |
13634 |
no acce |
17 |
perm |
43 |
R-free |
31 |
R-freea |
76 |
recr |
18519 |
free :这种类型的 chunk 不包含有效的对象,可以不受限制地被分配。
recr :意味着 recreatable ,这种类型的 chunk 里包含的对象可以在需要的时候被临时移走,并且在需要的时候重新创建。比如对于很多有关共享 SQL 语句的 chunk 就是 recreatable 的。
freeabl :这种类型的 chunk 包含的对象都是曾经被 session 使用过的,并且随后会被完全或部分释放。这种类型的 chunk 不能临时从内存移走,因为它们是在处理过程中间产生的,如果移走的话就无法被重建。
perm :意味着 permanent ,这种类型的 chunk 包含永久的对象,大型的 permanent 类型的 chunk 也可能含有可用空间,这部分可用空间可以在需要的时候释放回 shared pool 里。
(miki西游 @mikixiyou 原文链接: http://mikixiyou.iteye.com/blog/1667933 )
使用”heapdump at level 2” 将shared pool 空间dump 出来,可以看到heap 的组成。
使用的SQL 如下:
alter session set events 'immediate trace name heapdump level 2';
dump 出来的结果如下:
****************************************************** HEAP DUMP heap name="sga heap" desc=0x2000002c extent sz=0x32c8 alt=108 het=32767 rec=9 flg=-126 opc=0 parent=(nil) owner=(nil) nex=(nil) xsz=0x0 ****************************************************** HEAP DUMP heap name="sga heap(1,1)" desc=0x2001b598 extent sz=0xfc4 alt=108 het=32767 rec=9 flg=-126 opc=0 parent=(nil) owner=(nil) nex=(nil) xsz=0x1000000 EXTENT 0 addr=0x9d000000 Chunk 9d000038 sz= 24 R-freeable "reserved stoppe" Chunk 9d000050 sz= 839576 R-free " " Chunk 9d0ccfe8 sz= 24 R-freeable "reserved stoppe" Chunk 9d0cd000 sz= 10274952 free " " Chunk 9da99888 sz= 796 recreate "KGL handles " latch=(nil) Chunk 9da99ba4 sz= 1036 freeable "parameter table" Chunk 9da99fb0 sz= 96 freeable "library cache " Chunk 9da9a010 sz= 228 recreate "KGL handles " latch=(nil) Chunk 9da9a0f4 sz= 96 freeable "library cache " Chunk 9da9a154 sz= 284 recreate "KQR PO " latch=0x9baaf310 Chunk 9da9a270 sz= 284 recreate "KQR PO " latch=0x9baaf310 Chunk 9da9a38c sz= 540 recreate "KQR PO " latch=0x9baaf568 Chunk 9da9a5a8 sz= 96 freeable "library cache " Chunk 9da9a608 sz= 540 recreate "KGL handles " latch=(nil) Chunk 9da9a824 sz= 540 recreate "KGL handles " latch=(nil) Chunk 9da9aa40 sz= 540 recreate "KGL handles " latch=(nil) Chunk 9da9ac5c sz= 540 recreate "KGL handles " latch=(nil) Chunk 9da9ae78 sz= 540 recreate "KGL handles " latch=(nil)
在chunk 的 header 中,有一个16 字节的固定区域,保存分配该heap 内存的原因或者说是注释,如”KGL handles” 、”KQR PO” 等等。
Oracle shared pool 中这些物理内存的分配、管理都是由一个叫做KGH Heap Manager 的C 程序来实现的。Heap Manager 预先分配所有的shared pool 所定义的内存空间。Heap Manager 还管理PGA 内存,但这个操作需要经常同操作系统交互来分配和回收内存。
从逻辑角度看Oracle shared pool ,它主要分为library cache 、dictionary cache 和control structure 三个部分。
Shared pool 的library cache 主要保存了已执行的SQL 语句和PL/SQL 对象,以及它们的执行计划等等。
采用hash table 对这些对象进行管理。例如一个SQL 在经过hash 算法分析后得到一个hash 值。hash table 下由若干个hash bucket ,hash bucket 下又有若干个library cache handle 组成。这些handle 的组成部分包括name,namespace,lock owners,lock waiters,pin owners,pin waiters,flags,heap 0(object) 。其中heap 0 保存的是指向object 的指针。因此这个heap 0 也称为object 。如下图所示:
根据library cache 的结构,延伸到heap 0 这个级别上。heap 0 的组成部分包括object type,object name,flags,tables,data blocks 。其中tables 和data blocks 又进一步延伸。
tables 的组成部分包括dependency table ,child table ,translation table ,authorization table ,access table ,r-o dependency table ,schema name table 。
data blocks 的组成部分包括object, source,diana,pcode,mcode,errors,sql context 。其中source 也称为heap 1 用于存储sql 文本,sql context 称为heap 6 用于存储SQL 执行计划。如下图所示:
library cache 中不同bucket 的library cache object handle 是有不同类型的。可以根据object handle 中的namespace 进行区别。不同object handle 之间可能采用双向链表的形式相互关联。
如namespace 为CRSR 的,有parent cursor 和child cursor ,分别在不同的bucket 中的object handle 里。
使用”library_cache level 11 “将library cache 的内存dump 出来。
使用的SQL 如下:
alter session set events 'immediate trace name library_cache level 11';
dump 出来的结果如下:
BUCKET 5944: LIBRARY OBJECT HANDLE: handle=1895899e8 mtx=0x189589b18(1) cdp=1 name=select* from sys.obj$ where obj#=:x hash=8cd0bd4dbb09ea7c3d007f1ce9b01738 timestamp=08-21-2012 10:02:35 namespace= CRSR flags=RON/KGHP/TIM/PN0/SML/KST/DBN/MTX/[120100d0] kkkk-dddd-llll=0000-0001-0001 lock=N pin=0 latch#=6 hpc=0002 hlc=0002 lwt=0x189589a90[0x189589a90,0x189589a90] ltm=0x189589aa0[0x189589aa0,0x189589aa0] pwt=0x189589a58[0x189589a58,0x189589a58] ptm=0x189589a68[0x189589a68,0x189589a68] ref=0x189589ac0[0x189589ac0,0x189589ac0] lnd=0x189589ad8[0x189589ad8,0x189589ad8] LOCK OWNERS: lock user session count mode flags -------- -------- -------- ----- ---- ------------------------ 17f72e938 1852c9890 1852c9890 1 N [00] LIBRARY OBJECT: object=1786e6168 type=CRSR flags=EXS[0001] pflags=[0000] status=VALD load=0 CHILDREN: size=16 child# table reference handle ------ -------- --------- -------- 0 17816fa10 17816f680 144768330 DATA BLOCKS: data# heap pointer status pins change whr ----- -------- -------- --------- ---- ------ --- 0 144773248 1786e6280 I/P/A/-/- 0 NONE 00 BUCKET 5944 total object count=1
LIBRARY OBJECT HANDLE: handle=144768330 mtx=0x144768460(0) cdp=0 namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100] kkkk-dddd-llll=0000-0001-0001 lock=N pin=0 latch#=6 hpc=fffe hlc=fffe lwt=0x1447683d8[0x1447683d8,0x1447683d8] ltm=0x1447683e8[0x1447683e8,0x1447683e8] pwt=0x1447683a0[0x1447683a0,0x1447683a0] ptm=0x1447683b0[0x1447683b0,0x1447683b0] ref=0x144768408[0x17816f680,0x17816f680] lnd=0x144768420[0x144768420,0x144768420] CHILD REFERENCES: reference latch flags --------- ----- ------------------- 17816f680 11 CHL[02] LOCK OWNERS: lock user session count mode flags -------- -------- -------- ----- ---- ------------------------ 17f72f1d8 1852c9890 1852c9890 1 N [00] LIBRARY OBJECT: object=178161a10 type=CRSR flags=EXS[0001] pflags=[0000] status=VALD load=0 DEPENDENCIES: count=1 size=16 dependency# table reference handle position flags ----------- -------- --------- -------- -------- ------------------- 0 17837dae8 17837d828 189addbb8 17 DEP[01] AUTHORIZATIONS: count=1 size=16 minimum entrysize=16 00000000 00000000 00020000 00000000 ACCESSES: count=1 size=16 dependency# types ----------- ----- 0 0009 SCHEMA: count=1 size=262144 00000000 DATA BLOCKS: data# heap pointer status pins change whr ----- -------- -------- --------- ---- ------ --- 0 144e55298 178161b28 I/P/A/-/- 0 NONE 00 6 1786cd5a0 16ece5dc0 I/-/A/-/E 0 NONE 00