Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1786345
  • 博文数量: 413
  • 博客积分: 8399
  • 博客等级: 中将
  • 技术积分: 4325
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-09 10:44
文章分类

全部博文(413)

文章存档

2015年(1)

2014年(18)

2013年(39)

2012年(163)

2011年(192)

分类: Oracle

2012-09-27 21:13:19

参考:  

上接shared pool的深入(一)

其实我们可以从数据库内部监控shared pool的空间碎片情况.
这涉及到一个内部视图x$ksmsp

X$KSMSP的名称含义为: [K]ernal [S]torage [M]emory Management [S]GA Hea[P]
其中每一行都代表着shared pool中的一个chunk

首先记录一下测试环境:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

我们看一下x$ksmsp的结构:
SQL> desc x$ksmsp;
 Name              Null?    Type
 ----------------- -------- ------------
 ADDR                       RAW(4)
 INDX                       NUMBER
 INST_ID                    NUMBER
 KSMCHIDX                   NUMBER
 KSMCHDUR                   NUMBER
 KSMCHCOM                   VARCHAR2(16)
 KSMCHPTR                   RAW(4)
 KSMCHSIZ                   NUMBER
 KSMCHCLS                   VARCHAR2(8)
 KSMCHTYP                   NUMBER
 KSMCHPAR                   RAW(4)

我们关注以下几个字段:

KSMCHCOM是注释字段,每个内存块被分配以后,注释会添加在该字段中.
x$ksmsp.ksmchsiz代表块大小

x$ksmsp.ksmchcls列代表类型,主要有四类,说明如下:

SQL> select distinct ksmchcls from x$ksmsp;
KSMCHCLS
--------
recr
freeabl
R-freea
perm
R-free
free

6 rows selected.

free

Free chunks--不包含任何对象的chunk,可以不受限制的被分配.

recr
Recreatable chunks--包含可以被临时移出内存的对象,在需要的时候,这个对象可以
被重新创建.例如,许多存储共享sql代码的内存都是可以重建的.

freeabl
Freeable chunks--包含session周期或调用的对象,随后可以被释放.这部分内存有时候
可以全部或部分提前释放.但是注意,由于某些对象是中间过程产生的,这些对象不能
临时被移出内存(因为不可重建).

perm
Permanent memory chunks--包含永久对象.通常不能独立释放.

注:R是指---Reserved 
也就是shared_pool_reserved_size相关的chunk信息 http://www.itpub.net/thread-846660-1-1.html

我们可以通过查询x$ksmsp视图来考察shared pool中存在的内存片的数量

不过注意:Oracle的某些版本(如:10.1.0.2)在某些平台上(如:HP-UX PA-RISC 64-bit)查
询该视图可能导致过度的CPU耗用,这是由于bug引起的.

我们看一下测试:

初始启动数据库,x$ksmsp中存在8758个chunk
SQL> select count(*) from x$ksmsp;
  COUNT(*)
----------
      8758

执行查询:
SQL> select count(*) from dba_objects;
  COUNT(*)
----------
     50359
此时shared pool中的chunk数量增加
到了8811
SQL> select count(*) from x$ksmsp;
  COUNT(*)
----------
      8811

这就是由于shared pool中进行sql解析,请求空间,进而导致请求free空间,分配、分割从而产生了更多,更细碎的内存chunk

由此我们可以看出,如果数据库系统中存在大量的硬解析,不停请求分配free的shred pool内存除了必须的shared pool latch等竞争外,还不可避免的会导致shared pool中产生更多的内存碎片(当然,在内存回收时,你可能看到chunk数量减少的情况)

我们看以下测试:

首先重新启动数据库:SQL> startup force;
ORACLE instance started.

Total System Global Area  218103808 bytes
Fixed Size                  1218604 bytes
Variable Size              83888084 bytes
Database Buffers          130023424 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL>
创建一张临时表用以保存之前x$ksmsp的状态:
SQL>CREATE GLOBAL TEMPORARY TABLE e$ksmsp ON COMMIT PRESERVE ROWS AS
SELECT a.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 GROUP BY ksmchcom, ksmchcls) a
where 1 = 0
GROUP BY a.ksmchcom;
保存当前shared pool状态:
INSERT INTO E$KSMSP
SELECT      a.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
           GROUP BY ksmchcom, ksmchcls) a
 GROUP BY a.ksmchcom;
执行查询:
SQL> select count(*) from dba_objects;
  COUNT(*)
----------
     50359
比较前后shared pool内存分配的变化:
select c.ksmchcom,c.chunk,c.sum,b.chunk,b.sum,(c.chunk - b.chunk) c_diff,(c.sum -b.sum) s_diff
from
(SELECT   a.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
           GROUP BY ksmchcom, ksmchcls) a
 GROUP BY a.ksmchcom) c,e$ksmsp b
 where c.ksmchcom = b.ksmchcom and (c.chunk - b.chunk) <>0;

KSMCHCOM              CHUNK        SUM      CHUNK        SUM     C_DIFF     S_DIFF
---------------- ---------- ---------- ---------- ---------- ---------- ----------
free memory             473   13398952        514   13498700        -41     -99748
Heap0: KGL              641     687152        631     676432         10      10720
KGL handles            3408    1621416       3399    1617620          9       3796
KGLS heap               718     983556        705     969620         13      13936
obj stat memo           400     121600        399     121296          1        304
KQR SO                  643     391764        642     391224          1        540
PCursor                 677     725744        669     717168          8       8576
CCursor                 865     937772        863     935628          2       2144
sql area                789    3231856        776    3178608         13      53248
KQR PO                 3593    1831420       3581    1824940         12       6480

10 rows selected.

我们简单分析一下以上结果:
首先free memory的大小减少了99748(增加到另外五个组件中),这说明sql解析存储占用了一定的内存空间
而chunk从473增加为514,这说明内存碎片增加了.

在下面的部分中,我会着手介绍一下KGL handles, KGLS heap这两个非常重要的shared pool中的内存结构.


阅读(1672) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~