1.2.5 X$KSMSP视图
Shared Pool 的空间分配和使用情况,可以通过一个内部视图来观察,这个视图就是X$KSMSP。
X$KSMSP的名称含义为: [K]ernal [S]torage [M]emory Management [S]GA Hea[P]其中每一行都代表着Shared Pool中的一个Chunk。以下是x$ksmsp的结构:
12:03:45 sys@felix SQL>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)
12:06:29 sys@felix SQL>
这里需要关注一下以下几个字段。
(1)x$ksmsp.ksmchcom是注释字段,每个内存块被分配以后,注释会添加在该字段中。
(2)x$ksmsp.ksmchsiz代表块大小。
(3)x$ksmsp.ksmchcls列代表类型,主要有4类,具体说明如下。
(1)free:即Free Chunks,不包含任何对象的Chunk,可以不受限制的被自由分配。
(2)recr:即Recreatable Chunks,包含可以被临时移出内存的对象,在需要的时候,这个对象可以被重新创建。例如,许多存储共享SQL代码的内存都是可以重建的。
(3)freeable:即Freeable Chunks,包含session周期或调用的对象,随后可以被释放。这部分内存有时候可以全部或部分提前释放。但是注意,由于某些对象是中间过程产生的,这些对象不能临时被移出内存(因为不可重建)。
(4)perm:即Permanent Memory Chunks,包含永久对象,通常不能独立释放?
在这个测试数据库中,初始启动数据库,在x$ksmsp视图中存在12623个Chunk:
12:12:54 sys@felix SQL>select count(*) fromx$ksmsp;
COUNT(*)
----------
12623
12:12:56 sys@felix SQL>select count(*) fromdba_objects;
COUNT(*)
----------
75613
此时shared pool中的chunk数量增加
12:13:04 sys@felix SQL>select count(*) fromx$ksmsp;
COUNT(*)
----------
13892
12:13:09 sys@felix SQL>
这就是由于Shared Pool中进行SQL解析,请求空间,进而导致请求free空间分配、分割,从而产生了更多、更细碎的内存Chunk。
由此可以看出,如果数据库系统中存在大量的硬解析,不停请求分配free的Shared Pool内存,除了必需的SharedPool Latch等竞争外,还不可避免地会导致Shared Pool中产生更多的内存碎片(当然,在内存回收时,你可能看到Chunk数量减少的情况)。?
继续进行一点深入研究,首先重新启动数据库:
12:13:09 sys@felix SQL>startup force;
ORACLE instance started.
Total System Global Area 417546240 bytes
Fixed Size 2228944 bytes
Variable Size 335547696 bytes
Database Buffers 75497472 bytes
Redo Buffers 4272128 bytes
Database mounted.
Database opened.
12:16:41 sys@felix SQL>
创建一张临时表用以保存之前x$ksmsp的状态:
CREATE GLOBAL TEMPORARY TABLE e$ksmsp ON COMMITPRESERVE ROWS AS
SELECTa.ksmchcom,
SUM(a.CHUNK) CHUNK,
SUM (a.recr) recr,
SUM (a.freeabl) freeabl,
SUM (a.SUM) SUM
FROM (SELECT ksmchcom, COUNT (ksmchcom) CHUNK,
DECODE (ksmchcls, 'recr', SUM (ksmchsiz), NULL)recr,
DECODE (ksmchcls, 'freeabl', SUM (ksmchsiz), NULL)freeabl,
SUM(ksmchsiz) SUM
FROM x$ksmspGROUP BY ksmchcom, ksmchcls) a
where 1 = 0
GROUP BYa.ksmchcom;
保存当前Shared Pool状态:
INSERT INTO E$KSMSP
SELECTa.ksmchcom,
SUM(a.CHUNK) CHUNK,
SUM(a.recr) recr,
SUM(a.freeabl) freeabl,
SUM(a.SUM) SUM
FROM(SELECT ksmchcom,
COUNT(ksmchcom) CHUNK,
DECODE(ksmchcls, 'recr', SUM(ksmchsiz), NULL) recr,
DECODE(ksmchcls, 'freeabl', SUM(ksmchsiz), NULL) freeabl,
SUM(ksmchsiz) SUM
FROM x$ksmsp
GROUPBY ksmchcom, ksmchcls) a
GROUP BYa.ksmchcom /?
12:20:31 sys@felix SQL>INSERT INTO E$KSMSP
12:20:50 2 SELECT a.ksmchcom,
12:20:50 3 SUM(a.CHUNK) CHUNK,
12:20:50 4 SUM(a.recr) recr,
12:20:50 5 SUM(a.freeabl)freeabl,
12:20:50 6 SUM(a.SUM) SUM
12:20:50 7 FROM (SELECT ksmchcom,
12:20:50 8 COUNT(ksmchcom) CHUNK,
12:20:50 9 DECODE(ksmchcls, 'recr', SUM(ksmchsiz), NULL) recr,
12:20:50 10 DECODE(ksmchcls, 'freeabl',SUM(ksmchsiz), NULL) freeabl,
12:20:50 11 SUM(ksmchsiz)SUM
12:20:50 12 FROM x$ksmsp
12:20:50 13 GROUP BY ksmchcom,ksmchcls) a
12:20:50 14 GROUP BY a.ksmchcom ;
2788 rows created.
12:20:51 sys@felix SQL>?
执行查询:
12:22:30 sys@felix SQL>select count(*) fromdba_objects;
COU