瞭解X$KSMSP視圖:
Shared Pool的空間分配和使用情況,可以通過一個內部視圖來觀察,這個視圖就是X$KSMSP([K]ernal [S]torage [M]emory Management [S]GA Hea[P]),其中每一行都代表着Shared Pool中的一個Chunk。以下是X$KSMSP的結構:
sys@CCDB> desc x$ksmsp
Name Null? Type
------------------------ -------- ----------------
ADDR RAW(8)
INDX NUMBER
INST_ID NUMBER
KSMCHIDX NUMBER
KSMCHDUR NUMBER
KSMCHCOM VARCHAR2(16)
KSMCHPTR RAW(8)
KSMCHSIZ NUMBER
KSMCHCLS VARCHAR2(8)
KSMCHTYP NUMBER
KSMCHPAR RAW(8)
這裏需要關注一下以下幾個字段。
⑴ x$ksmsp.ksmchcom 是註釋字段,每個內存塊被分配以後,註釋會添加在該字段中。
⑵ x$ksmsp.ksmchsiz 代表塊大小。
⑶ x$ksmsp.ksmchcls 列代表類型,主要有4類,具體說明如下:
·free:即Free Chunks,不包含任何對象的Chunk,可以不受限制的被自由分配。
·recr:即Recreatable Chunks,包含可以被臨時移出內存的對象,在需要的時候,這個對象可以被重新創建。例如,許多存儲共享SQL代碼的內存都是可以重建的。
·freeable:即Freeable Chunks,包含session週期或調用的對象,隨後可以被釋放。這部分內存有時候可以全部或部分提前釋放。但是注意,由於某些對象是中間過程產生的,這些對象不能臨時被移出內存(因爲不可重建)。
·perm:即Permanent Memory Chunks,包含永久對象,通常不能獨立釋放。
從以上引用的trace文件中,摘出開頭一段,可以清楚地看到Oracle對這部分Chunk的記錄情況:
HEAP DUMP heap name="sga heap(1,0)" desc=0x2001aae4
extent sz=0xfc4 alt=108 het=32767 rec=9 flg=-126 opc=0
parent=(nil) owner=(nil) nex=(nil) xsz=0x400000
EXTENT 0 addr=0x41000000
Chunk 41000038 sz= 24 R-freeable "reserved stoppe"
Chunk 41000050 sz= 212888 R-free " "
Chunk 41033fe8 sz= 24 R-freeable "reserved stoppe"
Chunk 41034000 sz= 3981312 perm "perm " alo=3955992
EXTENT 1 addr=0x41400000
Chunk 41400038 sz= 24 R-freeable "reserved stoppe"
Chunk 41400050 sz= 212888 R-free " "
Chunk 41433fe8 sz= 24 R-freeable "reserved stoppe"
Chunk 41434000 sz= 2097168 perm "perm " alo=2097168
Chunk 41634010 sz= 1884144 free " "
可以通過查詢x$ksmsp視圖來考察Shared Pool中存在的內存片的數量,不過注意,Oracle的某些版本(如:10.1.0.2)在某些平臺上(如:HP-UX PA-RISC 64-bit)查詢該視圖可能導致過度的CPU耗用,這是由於Bug引起的。
看一下測試,在這個測試數據庫中,初始啓動數據庫,在x$ksmsp視圖中存在11361個Chunk:
sys@NEI> select count(*) from x$ksmsp;
COUNT(*)
----------
11361
執行查詢:
sys@NEI> select count(*) from dba_objects;
COUNT(*)
----------
50404
此時shared pool中的chunk數量增加:
sys@NEI> select count(*) from x$ksmsp;
COUNT(*)
----------
11428
這就是由於Shared Pool中進行SQL解析,請求空間,進而導致請求free空間分配、分割,從而產生了更多、更細碎的內存Chunk。
由此可以看出,如果數據庫系統中存在大量的硬解析,不停請求分配free的Shared Pool內存,除了必需的Shared Pool Latch等競爭外,還不可避免地會導致Shared Pool中產生更多的內存碎片(當然,在內存回收時,你可能看到Chunk數量減少的情況)。
繼續進行一點深入的研究,首先重新啓動數據庫:
sys@NEI> startup force
創建一張臨時表用以保存之前x$ksmsp的狀態:
sys@NEI> create global temporary table e$ksmsp on commit preserve rows as
2 select a.ksmchcom,
3 sum(a.chunk) chunk,
4 sum(a.recr) recr,
5 sum(a.freeabl) freeabl,
6 sum(a.sum) sum
7 from (select ksmchcom,count(ksmchcom) chunk,
8 decode(ksmchcls,'recr',sum(ksmchsiz),null) recr,
9 decode(ksmchcls,'freeabl',sum(ksmchsiz),null) freeabl,
10 sum(ksmchsiz) sum
11 from x$ksmsp group by ksmchcom,ksmchcls) a
12 where 1=0
13 group by a.ksmchcom;
Table created.
保存當前Shared Pool狀態:
sys@NEI> insert into e$ksmsp
2 select a.ksmchcom,
3 sum(a.chunk) chunk,
4 sum(a.recr) recr,
5 sum(a.freeabl) freeabl,
6 sum(a.sum) sum
7 from (select ksmchcom,count(ksmchcom) chunk,
8 decode(ksmchcls,'recr',sum(ksmchsiz),null) recr,
9 decode(ksmchcls,'freeabl',sum(ksmchsiz),null) freeabl,
10 sum(ksmchsiz) sum
11 from x$ksmsp group by ksmchcom,ksmchcls) a
12 group by a.ksmchcom;
85 rows created.
執行查詢:
sys@NEI> select count(*) from dba_objects;
COUNT(*)
----------
50405
比較前後Shared Pool內存分配的變化:
sys@NEI> select a.ksmchcom,a.chunk,a.sum,b.chunk,b.sum,(a.chunk-b.chunk) c_diff,(a.sum-b.sum) s_diff
2 from
3 (select a.ksmchcom,
4 sum(a.chunk) chunk,
5 sum(a.recr ) recr,
6 sum(a.freeabl) freeabl,
7 sum(a.sum) sum
8 from (select ksmchcom,count(ksmchcom) chunk,
9 decode(ksmchcls,'recr',sum(ksmchsiz),null) recr,
10 decode(ksmchcls,'freeabl',sum(ksmchsiz),null) freeabl,
11 sum(ksmchsiz) sum
12 from x$ksmsp
13 group by ksmchcom,ksmchcls) a
14 group by a.ksmchcom) a,e$ksmsp b
15 where a.ksmchcom=b.ksmchcom and (a.chunk-b.chunk) <>0;KSMCHCOM CHUNK SUM CHUNK SUM C_DIFF S_DIFF
---------------- ---------- ---------- ---------- ---------- ---------- ----------
free memory 219 21339452 208 22231952 11 -892500
Heap0: KGL 656 708884 624 674580 32 34304
trigger inform 6 2620 5 2560 1 60
KGL handles 3491 1709404 3248 1596568 243 112836
modification 14 28840 13 26780 1 2060
KGLS heap 1211 1550260 1150 1467528 61 82732
obj stat memo 296 89984 284 86336 12 3648
KQR SO 380 244880 346 226520 34 18360
kpscad: kpscsco 4 232 3 176 1 56
sql area:PLSQL 50 206980 46 190460 4 16520
PCursor 899 963728 851 912272 48 51456
CCursor 1447 1563120 1368 1478432 79 84688
library cache 1362 130812 1299 124736 63 6076
sql area 1184 4850764 1120 4588516 64 262248
PL/SQL DIANA 340 1392640 328 1343488 12 49152
KQR PO 2138 1074408 2016 1010576 122 63832
PL/SQL MPCODE 575 2476872 552 2376544 23 100328
CURSOR STATS 42 174048 41 169904 1 414418 rows selected.
簡單分析一下以上結果:首先free memory的大小減小了892500(增加到另外17個組件中),這說明SQL解析存儲佔用了一定的內存空間;而從208增加到219,這說明內存碎片增加了,碎片增加是共享池性能下降的開始。
- The End
http://www.dbtan.com/2009/11/xksmsp.html