深入理解shared pool共享池空间及library cache分配之ora-4031 系列一

结论

1,可以通过x$ksmsp分析共享池chunk的分配回收情况,深入分析ora-4031错误的原因
2,x$ksmsp的列ksmchcls为chunk的类型,共计6个值,具体如下:


KSMCHCLS
--------
R-free
R-freea
free
freeabl
perm
recr


6 rows selected.


3,关于上述ksmchcls列的不同含义,见下:
free:这种类型的chunk不包含有效的对象,可以不受限制的被分配。




recr:意味着recreatable,这种类型的chunks里包含的对象可以在需要的时候被临时移走,并且在需要的时候重新创建。比如对于很多有关共享SQL语句的chunks就是recreatable的。




freeabl:这种类型的chunks包含的对象都是曾经被session使用过的,并且随后会被完全或部分释放的。这种类型的chunks不能临时从内存移走,因为它们是在处理过程中间产生的,如果移走的话就无法被重建。




perm:意味着permanent,这种类型的chunks包含永久的对象,大型的permanent类型的chunks也可能含有可用空间,这部分可用空间可以在需要的时候释放回shared pool里。
当chunk属于free类型的时候,它既不属于library cache,也不属于dictionary cache.如果该chunk被用于存放SQL游标时,则该chunk进入library cache;同样,如果该chunk被用于存放数据字典的信息时,则该chunk进入dictionary cache.


仍有部分值没有解释的含义,还需要再查查资料


4,通过如下方法,模拟ora-4031错误


alter system set open_cursors=65535 scope=spfile;


create or replace procedure proc_4031(v_in int)
as
n number;
v_cycle number;
v_number number;
begin
v_cycle:=v_in;
dbms_random.seed(123456);
for i in 1..v_cycle loop
n:=dbms_random.value;
select n into v_number from dual;
end loop;
end;
/




5,ora-4031错误信息的含义:
ERROR at line 1:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared
pool","unknown object","sga heap(4,0)","library cache")


每一个参数为共享池
第二个参数要在共享池中分配的对象
第三个参数即要在共享池哪个heap中分配内存空间
第四个参数,即要在共享池哪个组件中分配内存空间,到底是library cache,还是row cache或是其它的组件


知道这个含义,在分析ORA-4031的TRC文件,就查看对应的heap即可进行针对性分析


6,经过本文测试,一般情况从共享池分配内存只会从FREE LIST中的BUCKET中的CHUNK进行分配内存,而不会从reserved free list或者unpinned recreatable chunks以及permanent chunks分配内存
7, 既然上述ora-4031是基于library cache,学习了dump library cache的方法
   即oradebug setmypid
     oradebug dump library_cache 3;--3是概要DUMP,而6则把每个BUCKET中具体内容也DUMP出来
     oradebug tracefile_name


    也就是说6级产生的信息比3级要全面丰富得多


8,bucket里面包括很多library object handle,我估计如果一个bucket里面的library object handle多了,这些很多个连接到同一个bucket的library object handle就是chain构,好像我查了下资料,仅在buffer cache
   有chain的概念结构


9, x$kglob可以理解对应每个library object handle, 可以把library object handle理解不同一的内存对象,可能是表,也可能是依整表的SQL或存储过程等等
10,library cache dump产生的TRC文件结构为:
   10.1,LIBRARY CACHE STATISTICS:
namespace           gets hit ratio      pins hit ratio    reloads   invalids
-------------- --------- --------- --------- --------- ---------- ----------
CRSR              119123     0.411    535527     0.801       1117        568
TABL               10367     0.711    262568     0.976        665          0
BODY                 309     0.838     16219     0.996          7          0
TRGR                  97     0.907       101     0.911          0          0
INDX                 352     0.267      1783     0.781          0          0
CLST                 259     0.961       666     0.982          2          0
KGLT                   0     0.000         0     0.000          0          0
PIPE                   0     0.000         0     0.000          0          0
中间略
NSCPD                  0     0.000         0     0.000          0          0
JSLV                   0     0.000         0     0.000          0          0
MODL                   0     0.000         0     0.000          0          0
CUMULATIVE        164614     0.354    872633     0.833       1801        568


   10.2,第二部分,好像存储各种锁,PIN,以及KGL相关的HANDLE之类的对象占用的PERMANENT空间相关信息,包括对应的LATCH个数,消耗内存空间大小,管理LIBRARY CACHE内存分配的FREE LIST中CHUNK的个数以及对象个数(这个对象不知为何义)
再罗列下:存储在LIBRARY CACHE中的包括:加载lock,kgl pin,kgl lock,kgl lock,kgl s handle,kgl m handle,kgl l handle,kgl handle,kgl object,kgl handle dependents
Permanent space allocated for Load Locks
LATCH:0  TOTAL SPACE: 4104
FREELIST CHUNK COUNT:57  OBJECT SIZE:72




Permanent space allocated for KGL pins
LATCH:0  TOTAL SPACE: 28560
FREELIST CHUNK COUNT:66  OBJECT SIZE:136




Permanent space allocated for KGL locks
LATCH:0  TOTAL SPACE: 23676752
FREELIST CHUNK COUNT:64064  OBJECT SIZE:184




  10.3,library cache hash table的大小,以及个数,个数我估计是bucket个数,且列出包括20个chains以上的bucket个数,基于分组列出
LIBRARY CACHE HASH TABLE: size=131072 count=64903
Buckets with more than 20 objects:
NONE
Hash Chain Size     Number of Buckets
---------------     -----------------
              0                 79861  --如下可见大多bucket没有对应的chain
              1                 39579
              2                  9799  --有2个chain的bucket共计9799个
              3                  1635
              4                   173
              5                    21
              6                     4
              7                     0
              8                     0
              9                     0
             10                     0
             11                     0
             12                     0
             13                     0
             14                     0
             15                     0
             16                     0
             17                     0
             18                     0
             19                     0
             20                     0
            >20                     0




11,library cache buckets的个数是固定的值
131072


12,x$kglob的重列的相关含义:
好,再列举下x$kglob的重要列的含义
X$kglob 表说明如下:
Kglhdadr (children address) LIBRARY OBJECT HANDLE: handle
Kglhdpar (parent address) LIBRARY OBJECT HANDLE:handle
Kglnaown 依赖object的owner name
Kglnahsh sql的hash value (v$sql 中的hash_value)
Kglnahsv sql 的hash value (长串格式:9a5fb5d584eb42ce5f55b9c92930cf55)
Kglhdobj LIBRARY OBJECT: object
Kglobhd0 data#=0 的 heap 地址
Kglobhd1
Kglobhd2
Kglobhd3..7           


引发的问题:



1,为何在共享池中分配内存只会特定的从heap 进行分配chunk呢,这是什么算法或机制呢?
2,何时会从reserved free list及unpinned recreatable chunks以及permanent chunks分配内存呢?
3, 同一个bucket里面可能会包括2个以上的library object handle吗?




测试



---oracle version
SQL> select * from v$version where rownum=1;


BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi


---ora-4031错误
SQL> host oerr ora 4031
04031, 00000, "unable to allocate %s bytes of shared memory (\"%s\",\"%s\",\"%s\",\"%s\")"
// *Cause:  More shared memory is needed than was allocated in the shared
//          pool.
// *Action: If the shared pool is out of memory, either use the
//          dbms_shared_pool package to pin large packages,
//          reduce your use of shared memory, or increase the amount of
//          available shared memory by increasing the value of the
//          INIT.ORA parameters "shared_pool_reserved_size" and 
//          "shared_pool_size".
//          If the large pool is out of memory, increase the INIT.ORA
//          parameter "large_pool_size".  




解决方法:
1,使用dbms_shared_pool.keep过程pin掉大对象在共享池,防止老化
2,增加共享池大小,即调整参数shared_pool_reserved_size及shared_pool_size
3,如果提示大池不够用,增大large_pool_size大小




---查看共享池中不同类型的chunk,可知共计6种类型
SQL> select distinct ksmchcls from x$ksmsp order by 1;


KSMCHCLS
--------
R-free
R-freea
free
freeabl
perm
recr


6 rows selected.


上述不同类型chunk的分组大小
SQL> select ksmchcls,sum(ksmchsiz) from x$ksmsp group by ksmchcls order by 2;


KSMCHCLS SUM(KSMCHSIZ)
-------- -------------
R-freea           1536
R-free        13431936
recr          14197824
freeabl       18410408
perm          79687680
free         142704664


6 rows selected.


可见可用共享池空间为136M左右
SQL> select 142704664/1024/1024 from dual;


142704664/1024/1024
-------------------
         136.093773


生成一个新SQL
SQL> show user
USER is "SCOTT"
SQL> create table t_pool(a int,b int);


Table created.


SQL> insert into t_pool values(1,1);


1 row created.


SQL> commit;


Commit complete.  


SQL> select ksmchcls,sum(ksmchsiz) from x$ksmsp group by ksmchcls order by 2;


KSMCHCLS SUM(KSMCHSIZ)
-------- -------------
R-freea           1536  --未变化
R-free        13431936  --未变化
recr          14295608  --变化,变大
freeabl       18593744  --变化,变大
perm          79687680  --未变化
free         142423544  --变化,变小


6 rows selected.




SQL> select * from t_pool;


         A          B
---------- ----------
         1          1




同上理,共享池CHUNK继续变化,综上可见仅recr,freeabl,free类型的CHUNK会发生变化,而R-FREEA,R-FREE,PERM不会发生变化
SQL> select ksmchcls,sum(ksmchsiz) from x$ksmsp group by ksmchcls order by 2;


KSMCHCLS SUM(KSMCHSIZ)
-------- -------------
R-freea           1536
R-free        13431936
recr          14317360
freeabl       18649352
perm          79687680
free         142346184


6 rows selected.


上述不同类型CHUNK的含义:
free:这种类型的chunk不包含有效的对象,可以不受限制的被分配。




recr:意味着recreatable,这种类型的chunks里包含的对象可以在需要的时候被临时移走,并且在需要的时候重新创建。比如对于很多有关共享SQL语句的chunks就是recreatable的。




freeabl:这种类型的chunks包含的对象都是曾经被session使用过的,并且随后会被完全或部分释放的。这种类型的chunks不能临时从内存移走,因为它们是在处理过程中间产生的,如果移走的话就无法被重建。




perm:意味着permanent,这种类型的chunks包含永久的对象,大型的permanent类型的chunks也可能含有可用空间,这部分可用空间可以在需要的时候释放回shared pool里。
当chunk属于free类型的时候,它既不属于library cache,也不属于dictionary cache.如果该chunk被用于存放SQL游标时,则该chunk进入library cache;同样,如果该chunk被用于存放数据字典的信息时,则该chunk进入dictionary cache.
在shared pool里,可用的chunk(free类型)会被串起来成为可用链表(free lists)或者也可以叫做buckets(一个可用链表也就是一个bucket)。我们可以使用下面的命令将shared pool的内容转储出来看看这些bucket.




SQL> select 'abcccccccccccccccccccccccccc' v_str from dual;


V_STR
----------------------------
abcccccccccccccccccccccccccc




SQL> select 'abcccccccccccccccccccccccccc'||'abc' v_str from dual;


V_STR
-------------------------------
abccccccccccccccccccccccccccabc


SQL> select ksmchcls,sum(ksmchsiz) from x$ksmsp group by ksmchcls order by 2;


KSMCHCLS SUM(KSMCHSIZ)
-------- -------------
R-freea           1536
R-free        13431936
recr          14332392
freeabl       18653768
perm          79687680
free         142326736


6 rows selected.


创建一个存储过程
create or replace procedure proc_4031(v_in int)
as
n number;
v_cycle number;
v_number number;
begin
v_cycle:=v_in;
dbms_random.seed(123456);
for i in 1..v_cycle loop
n:=dbms_random.value;
select n into v_number from dual;
end loop;
end;
/


通过这种方式,很难模拟出ORA-4031错误
SQL> exec proc_4031(10000000);




SQL> select count(*) from x$ksmsp;


  COUNT(*)
----------
     38633


SQL> 
SQL> 
SQL> 
SQL> select count(*) from x$ksmsp;


  COUNT(*)
----------
     38634




SQL> select sid from v$mystat where rownum=1;


       SID
----------
       122




SQL> select 'abc' from dual;


'AB
---
abc


SQL> select sid,serial#,prev_sql_id,sql_id from v$session where sid=122;


       SID    SERIAL# PREV_SQL_ID   SQL_ID
---------- ---------- ------------- -------------
       122         90 3y2rwdgbrygbz chsyqm9x25nwa




SQL> col sql_text for a100
SQL> select sql_id,sql_text from v$sql where sql_id='3y2rwdgbrygbz';


SQL_ID        SQL_TEXT
------------- ----------------------------------------------------------------------------------------------------
3y2rwdgbrygbz select 'abc' from dual




用网上如下脚本未模拟出ORA-4031错误
declare
msql varchar2(100);
mcur number;
mstat number;
jg varchar2(2000);
cg number;
begin for i in 1..1000000000 loop
mcur:=dbms_sql.open_cursor;
msql:='select deptno from dept where deptno='||i;
dbms_sql.parse(mcur,msql,dbms_sql.native);
mstat:=dbms_sql.execute(mcur);
end loop;
end;
/                   


加大open_cursors=65535后,模拟出ora-4031错误,open_cursos最大值为65535
SQL> show parameter cursor


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT
cursor_space_for_time                boolean     FALSE
open_cursors                         integer     50000
session_cached_cursors               integer     20
SQL> alter system set open_cursors=65536;
alter system set open_cursors=65536
*
ERROR at line 1:
ORA-00068: invalid value 65536 for parameter open_cursors, must be between 0
and 65535




SQL> alter system set open_cursors=65535;


System altered.


SQL> show parameter open_cursors


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
open_cursors                         integer     65535




SQL> declare
msql varchar2(100);
mcur number;
mstat number;
  2    3    4    5  jg varchar2(2000);
  6  cg number;
  7  begin for i in 1..1000000000 loop
  8  mcur:=dbms_sql.open_cursor;
  9  msql:='select deptno from dept where deptno='||i;
 10  dbms_sql.parse(mcur,msql,dbms_sql.native);
 11  mstat:=dbms_sql.execute(mcur);
 12  end loop;
 13  end;
 14  /  
declare
*
ERROR at line 1:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared
pool","unknown object","sga heap(4,0)","library cache")
ORA-06512: at "SYS.DBMS_SYS_SQL", line 909
ORA-06512: at "SYS.DBMS_SQL", line 39
ORA-06512: at line 10




SQL> select count(*) from dba_objects;
select count(*) from dba_objects
                     *
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 2
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared
pool","VIEW$","sga heap(4,0)","library cache")


同时在alert也报一系列的ORA-4031错误
Fri Nov 20 05:56:05 EST 2015
Errors in file /home/ora10g/admin/ora10g/bdump/ora10g_smon_3217.trc:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared pool","COL_USAGE$","sga heap(4,0)","library cache")
Fri Nov 20 05:56:06 EST 2015
Errors in file /home/ora10g/admin/ora10g/bdump/ora10g_smon_3217.trc:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared pool","COL_USAGE$","sga heap(4,0)","library cache")
Fri Nov 20 05:56:07 EST 2015
Errors in file /home/ora10g/admin/ora10g/bdump/ora10g_smon_3217.trc:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared pool","COL_USAGE$","sga heap(4,0)","library cache")
Fri Nov 20 05:56:08 EST 2015
Errors in file /home/ora10g/admin/ora10g/bdump/ora10g_smon_3217.trc:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared pool","COL_USAGE$","sga heap(4,0)","library cache")
Fri Nov 20 05:56:09 EST 2015
Errors in file /home/ora10g/admin/ora10g/bdump/ora10g_smon_3217.trc:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared pool","COL_USAGE$","sga heap(4,0)","library cache")
Fri Nov 20 05:56:19 EST 2015
Errors in file /home/ora10g/admin/ora10g/bdump/ora10g_smon_3217.trc:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared pool","COL_USAGE$","sga heap(4,0)","library cache


好像有空闲的共享池空间,为何报ORA-4031错误
SQL> select ksmchcls,count(*) from x$ksmsp where ksmchsiz>4080 group by ksmchcls;


KSMCHCLS   COUNT(*)
-------- ----------
freeabl       37714
recr          32116
perm              6
R-free           36
free            737


分析下共享池的DUMP,从上述ORA-4031报错是在ORA-04031: unable to allocate 4080 bytes of shared memory ("shared
pool","VIEW$","sga heap(4,0)","library cache") ,可知是在heap 4不能分配到空间,下面分析这个HEAP即可


我们就来分析如下的ORA-4031错误
ERROR at line 1:
ORA-04031: unable to allocate 4080 bytes of shared memory ("shared
pool","unknown object","sga heap(4,0)","library cache")
ORA-06512: at "SYS.DBMS_SYS_SQL", line 909
ORA-06512: at "SYS.DBMS_SQL", line 39
ORA-06512: at line 10




HEAP DUMP heap name="sga heap(4,0)"  desc=0x60051858
 extent sz=0xfe0 alt=216 het=32767 rec=9 flg=-126 opc=0
 parent=(nil) owner=(nil) nex=(nil) xsz=0x1000000
 latch set 4 of 5
 durations enabled for this heap
 reserved granules for root 0 (granule size 16777216)
EXTENT 0 addr=0x7a000000
  Chunk        07a000058 sz=       48  R-freeable  "reserved stoppe"
  Chunk        07a000088 sz=   839496  R-free      "               "
  Chunk        07a0ccfd0 sz=       48  R-freeable  "reserved stoppe"
  Chunk        07a0cd000 sz= 15934392    perm      "perm           "  alo=15934392
  Chunk        07afff3b8 sz=     3144    free      "               "
EXTENT 1 addr=0x9c000000
  Chunk        09c000058 sz=       48  R-freeable  "reserved stoppe"
  Chunk        09c000088 sz=   839496  R-free      "               "
  Chunk        09c0ccfd0 sz=       48  R-freeable  "reserved stoppe"
  Chunk        09c0cd000 sz= 15935336    perm      "perm           "  alo=15935336
  Chunk        09cfff768 sz=     2200    free      "               "
Total heap size    = 33554256




共享池分配会优先从free list分配chunk,但里面的2个chunk皆不到4080byte
FREE LISTS:
 Bucket 0 size=32
 Bucket 1 size=40
 Bucket 2 size=48
 Bucket 3 size=56
 Bucket 4 size=64
 中间略
 Bucket 197 size=2008
 Bucket 198 size=2056
 Bucket 199 size=2104
 Bucket 200 size=2152
 Bucket 201 size=2200
  Chunk        09cfff768 sz=     2200    free      "               "
 Bucket 202 size=2248
 Bucket 203 size=2296
 中间略
 Bucket 220 size=3112
  Chunk        07afff3b8 sz=     3144    free      "               "
 Bucket 221 size=3160
 中间略
 Bucket 254 size=65560
Total free space   =     5344


可见不会从预备的保留自由列表分配chunk
RESERVED FREE LISTS:
 Reserved bucket 0 size=32
 Reserved bucket 1 size=4400
 Reserved bucket 2 size=8216
 Reserved bucket 3 size=8696
 Reserved bucket 4 size=8704
 Reserved bucket 5 size=8712
 Reserved bucket 6 size=8720
 Reserved bucket 7 size=9368
 Reserved bucket 8 size=9376
 Reserved bucket 9 size=12352
 Reserved bucket 10 size=12360
 Reserved bucket 11 size=16408
 Reserved bucket 12 size=32792
 Reserved bucket 13 size=65560
  Chunk        07a000088 sz=   839496  R-free      "               "  --839496bytes大小的chunk
  Chunk        09c000088 sz=   839496  R-free      "               "
Total reserved free space   =  1678992


也没有从未PIN住的可重建的CHUNK(LRU优先)要分配CHUNK
UNPINNED RECREATABLE CHUNKS (lru first):
  Chunk        0a1fd04b8 sz=       56    recreate  "fixed allocatio"  latch=0x60013968
  Chunk        0a1fc1010 sz=      560    recreate  "KQR PO         "  latch=0x9b56d7f8

  Chunk        0a1fb4470 sz=      560    recreate  "KQR PO         "  latch=0x9b56d7f8
  Chunk        0a1fb4240 sz=      560    recreate  "KQR PO         "  latch=0x9b56d7f8
  Chunk        0a1faed30 sz=      560    recreate  "KQR PO         "  latch=0x9b56d7f8


也没有从永久性的CHUNKS列表中分配CHUNK
  PERMANENT CHUNKS:
  Chunk        07a0cd000 sz= 15934392    perm      "perm           "  alo=15934392
  Chunk        09c0cd000 sz= 15935336    perm      "perm           "  alo=15935336
Permanent space    = 31869728


引申一下,可见一般情况从共享池分配内存只会从FREE LIST中的BUCKET中的CHUNK进行分配内存,而不会从reserved free list或者unpinned recreatable chunks以及permanent chunks分配内存










这里就出现几个个问题,
1,为何只会从heap 4进行分配chunk呢,这是什么算法或机制呢?
2,何时会从reserved free list及unpinned recreatable chunks以及permanent chunks分配内存呢?




既然上述ORA-4031报错全与LIBRARY CACHE有关,我们DUMP下它的内容分析下,看可否的到相关的线索


SQL> oradebug setmypid
Statement processed.
SQL> oradebug dump library_cache 3
Statement processed.
SQL> oradebug tracefile_name
/home/ora10g/admin/ora10g/udump/ora10g_ora_23356.trc


第一部分,不过好像内容要比v$librarycache记录要多,不知为何
SQL> select count(*) from v$librarycache;


  COUNT(*)
----------
        11


 --namespace要远远大于11个哟,暂且搁置此问题       
LIBRARY CACHE STATISTICS:
namespace           gets hit ratio      pins hit ratio    reloads   invalids
-------------- --------- --------- --------- --------- ---------- ----------
CRSR              119123     0.411    535527     0.801       1117        568
TABL               10367     0.711    262568     0.976        665          0
BODY                 309     0.838     16219     0.996          7          0
TRGR                  97     0.907       101     0.911          0          0
INDX                 352     0.267      1783     0.781          0          0
CLST                 259     0.961       666     0.982          2          0
KGLT                   0     0.000         0     0.000          0          0
PIPE                   0     0.000         0     0.000          0          0
中间略
NSCPD                  0     0.000         0     0.000          0          0
JSLV                   0     0.000         0     0.000          0          0
MODL                   0     0.000         0     0.000          0          0
CUMULATIVE        164614     0.354    872633     0.833       1801        568


第二部分,好像存储各种锁,PIN,以及KGL相关的HANDLE之类的对象占用的PERMANENT空间相关信息,包括对应的LATCH个数,消耗内存空间大小,管理LIBRARY CACHE内存分配的FREE LIST中CHUNK的个数以及对象个数(这个对象不知为何义)
再罗列下:存储在LIBRARY CACHE中的包括:加载lock,kgl pin,kgl lock,kgl lock,kgl s handle,kgl m handle,kgl l handle,kgl handle,kgl object,kgl handle dependents
Permanent space allocated for Load Locks
LATCH:0  TOTAL SPACE: 4104
FREELIST CHUNK COUNT:57  OBJECT SIZE:72




Permanent space allocated for KGL pins
LATCH:0  TOTAL SPACE: 28560
FREELIST CHUNK COUNT:66  OBJECT SIZE:136




Permanent space allocated for KGL locks
LATCH:0  TOTAL SPACE: 23676752
FREELIST CHUNK COUNT:64064  OBJECT SIZE:184




Permanent space allocated for KGL S handles
LATCH:0  TOTAL SPACE: 31474536
FREELIST CHUNK COUNT:0  OBJECT SIZE:488




Permanent space allocated for KGL M handles
LATCH:0  TOTAL SPACE: 233920
FREELIST CHUNK COUNT:5  OBJECT SIZE:680




Permanent space allocated for KGL L handles
LATCH:0  TOTAL SPACE: 87048
FREELIST CHUNK COUNT:46  OBJECT SIZE:936




Permanent space allocated for KGL A handles
LATCH:0  TOTAL SPACE: 11121176
FREELIST CHUNK COUNT:53  OBJECT SIZE:344




Permanent space allocated for KGL objects
LATCH:0  TOTAL SPACE: 9297216
FREELIST CHUNK COUNT:17  OBJECT SIZE:144




Permanent space allocated for KGL handle dependents
LATCH:0  TOTAL SPACE: 784728
FREELIST CHUNK COUNT:49  OBJECT SIZE:24




第三部分,library cache hash table的大小,以及个数,个数我估计是bucket个数,且列出包括20个chains以上的bucket个数,基于分组列出
LIBRARY CACHE HASH TABLE: size=131072 count=64903
Buckets with more than 20 objects:
NONE
Hash Chain Size     Number of Buckets
---------------     -----------------
              0                 79861  --如下可见大多bucket没有对应的chain
              1                 39579
              2                  9799  --有2个chain的bucket共计9799个
              3                  1635
              4                   173
              5                    21
              6                     4
              7                     0
              8                     0
              9                     0
             10                     0
             11                     0
             12                     0
             13                     0
             14                     0
             15                     0
             16                     0
             17                     0
             18                     0
             19                     0
             20                     0
            >20                     0




SQL> create table t_libcache(a int);


Table created.


SQL> insert into t_libcache values(1);


1 row created.


SQL> commit;


Commit complete.


SQL> select * from t_libcache;


         A
----------
         1




再次dump library cache,与上述进行对比


可见
Buckets with more than 20 objects:
NONE
Hash Chain Size     Number of Buckets
---------------     -----------------
              0                 79796
              1                 39617
              2                  9820
              3                  1641
              4                   173
              5                    21
              6                     4
              7                     0
              8                     0
              9                     0
             10                     0
             11                     0
             12                     0
             13                     0
             14                     0
             15                     0
             16                     0
             17                     0
             18                     0
             19                     0
             20                     0
            >20                     0




数据库有个参数与bucket个数有关,共计32768个bucket
_db_block_hash_buckets                             32768                                              Number of database block hash buckets   




但上述的bucket个数明显要大于32768,可见不是一回事


经计算可见上述library cache中用于空间分配的hash bucket个数共计131072,并且是固定的大小
SQL> select 79796+39617+9820+1641+173+21+4 from dual;


79796+39617+9820+1641+173+21+4
------------------------------
                        131072


SQL> select 79861+39579+9799+1635+173+21+4  from dual;


79861+39579+9799+1635+173+21+4
------------------------------
                        131072      


但又想到一个参数,hash bucket个数与下述参数刚好一致,这是一回事呢,经测试,hash_area_size不是控制library cache hash bucket个数的参数
并且没有找到控制library cache hash bucket个数的参数,或者由ORACLE内部算法控制,具体原因暂时未知
hash_area_size                                     131072                                             size of in-memory hash work area   


很简单,我调整下hash_area_size,再dump library cache,即知


SQL> alter system set hash_area_size=131999;
alter system set hash_area_size=131999
                 *
ERROR at line 1:
ORA-02096: specified initialization parameter is not modifiable with this option


hash_area_size必须重启库方可生效
SQL> alter system set hash_area_size=131999 scope=spfile;


System altered.


SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-32004: obsolete and/or deprecated parameter(s) specified
ORACLE instance started.


Total System Global Area 1157627904 bytes
Fixed Size                  2095800 bytes
Variable Size            1090520392 bytes
Database Buffers           33554432 bytes
Redo Buffers               31457280 bytes
Database mounted.
Database opened.
SQL>         


SQL> show parameter hash_area_size


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
hash_area_size                       integer     131999


Hash Chain Size     Number of Buckets
---------------     -----------------
              0                130101
              1                   967
              2                     4
              3                     0
              4                     0
              5                     0
              6                     0
              7                     0
              8                     0
              9                     0
             10                     0
             11                     0
             12                     0
             13                     0
             14                     0
             15                     0
             16                     0
             17                     0
             18                     0
             19                     0
             20                     0
            >20                     0                


可见library cache hash bucket个数还是131072,而非由hash_area_size控制 
SQL> select 130101+967+4 from dual;


130101+967+4
------------
      131072


后来也没有相到相关的参数,不过改造了一个SQL脚本,以后分析可以用脚本进行反推到某个数据库参数,列举于此,我认为此脚本的价值很大
set linesize 300
col name_1 for a50
col value_1 for a50
col desc1 for a50


select
ksppinm as name_1,
ksppstvl as value_1,
ksppdesc as desc1
from x$ksppi x, x$ksppcv y
where (x.indx = y.indx) and lower(ksppstvl) like '%&val%';


再以oradebug dump library_cache 6进行DUMP,分析更为详细 的LIBRARY CACHE内容
仅列出与oradebug dump library_cache 3不同的内容进行讲解


列出library cache 中所有bucket的信息,bucket里面是library object handle可以理解为不同的内存对象,有SQL,有存储过程,也有其它的对象,其handle对应x$kglob中的kglhdadr
可以理解为library cache中的内容是存储在bucket中,而每个bucket包括不同的library object handle
BUCKET 64970:
  LIBRARY OBJECT HANDLE: handle=9ff11880 mtx=0x9ff119b0(0) lct=0 pct=0 cdp=0
  name=SYS.UTL_RECOMP 
  hash=d5f7067038c28d08af944250a59afdca timestamp=04-20-2010 08:25:21
  namespace=TABL flags=KGHP/TIM/SML/[02000000]
  kkkk-dddd-llll=0000-0000-0000 lock=0 pin=0 latch#=1 hpc=0000 hlc=0000
  lwt=0x9ff11928[0x9ff11928,0x9ff11928] ltm=0x9ff11938[0x9ff11938,0x9ff11938]
  pwt=0x9ff118f0[0x9ff118f0,0x9ff118f0] ptm=0x9ff11900[0x9ff11900,0x9ff11900]
  ref=0x9ff11958[0x9ff11958,0x9ff11958] lnd=0x9ff11970[0x9ff11758,0x9ff25d98]
  BUCKET 64970 total object count=1


SQL> select addr,KGLHDADR from x$kglob where lower(kglhdadr)='000000009fe4a098';


ADDR             KGLHDADR            
---------------- ---------------- 
00002B934B552128 000000009FE4A098  




除了上述的bucket,还有若名列表,也是包括多个不同的library object handle,具体为何ORACLE不会这些LIBRARY OBJECT HANDLE放到对应的bucket中,暂时原因不知
ANONYMOUS LIST:
  LIBRARY OBJECT HANDLE: handle=9fe356f0 mtx=0x9fe35820(0) lct=2 pct=6 cdp=0
  namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100]
  kkkk-dddd-llll=0000-0001-0001 lock=0 pin=0 latch#=1 hpc=fffe hlc=fffe
  lwt=0x9fe35798[0x9fe35798,0x9fe35798] ltm=0x9fe357a8[0x9fe357a8,0x9fe357a8]
  pwt=0x9fe35760[0x9fe35760,0x9fe35760] ptm=0x9fe35770[0x9fe35770,0x9fe35770]
  ref=0x9fe357c8[0x9ace88c0,0x9ace88c0] lnd=0x9fe357e0[0x9fe357e0,0x9fe357e0]
中间内容略
  kkkk-dddd-llll=0000-0001-0001 lock=0 pin=0 latch#=1 hpc=0000 hlc=0000
  lwt=0x9fe36b18[0x9fe36b18,0x9fe36b18] ltm=0x9fe36b28[0x9fe36b28,0x9fe36b28]
  pwt=0x9fe36ae0[0x9fe36ae0,0x9fe36ae0] ptm=0x9fe36af0[0x9fe36af0,0x9fe36af0]
  ref=0x9fe36b48[0x9aced298,0x9aced298] lnd=0x9fe36b60[0x9fe36b60,0x9fe36b60]
    LIBRARY OBJECT: object=9acecb30


最后一部分是具有依赖对象的handle列,其含义暂时未知
LIST OF HANDLES WITH DEPENDENTS:
LATCH=0 unpin_call_count=5 hd_count=776 hd_unpinned_count=4
9ff9a9d0 -> 9ff96730 -> 9ff940b8 -> 9ff931d0 -> 9ff922e8 -> 9ff891e8 -
中间内容略
 -> 9fe41c30 -> 9fe41958 -> 9fe41680 -> 9fe413a8 -> 9fe410d0 -> 9fe40df8 9fe3d9f8 -> 9fe3d720 -> 9fe3d230 -> 9fe38480 -> 
9fe379e0 -> 9fe367b0




为了加深理解,我们现在创建一个新的SQL,然后DUMP下进行对比
SQL> create table t_libcache2(a int);


Table created.


SQL> select count(*) from t_libcache2;


  COUNT(*)
----------
         0


SQL> select sql_id,sql_text,address,hash_value from v$sql where sql_text like '%select count(*) from t_libcache2%';


SQL_ID        SQL_TEXT                                           ADDRESS          HASH_VALUE
------------- -------------------------------------------------- ---------------- ----------
2dqgyd70ag5p7 select count(*) from t_libcache2                   000000009FD7D038 3232208551




但好像没有在x$kglob中记录
SQL> select addr,KGLHDADR from x$kglob where kglhdadr='000000009FD7D038';


ADDR             KGLHDADR
---------------- ----------------
00002B521C377E80 000000009FD7D038


可见已经上述的sql已存储到bucket 104103的library object handle中,而且library cache dump的handle addr仅为低8位,且为小写,而在x$kglob的列kghhdadr却为16列的大写,一定要注意
BUCKET 104103:
  LIBRARY OBJECT HANDLE: handle=9fd7d038 mtx=0x9fd7d168(1) lct=3 pct=1 cdp=1
  name=select count(*) from t_libcache2
  hash=a1dca2c74e5cd69526d9fe69c0a796a7 timestamp=11-20-2015 10:07:13
  namespace=CRSR flags=RON/KGHP/TIM/PN0/SML/KST/DBN/MTX/[120100d0]
  kkkk-dddd-llll=0000-0001-0001 lock=N pin=0 latch#=1 hpc=0002 hlc=0002
  lwt=0x9fd7d0e0[0x9fd7d0e0,0x9fd7d0e0] ltm=0x9fd7d0f0[0x9fd7d0f0,0x9fd7d0f0]
  pwt=0x9fd7d0a8[0x9fd7d0a8,0x9fd7d0a8] ptm=0x9fd7d0b8[0x9fd7d0b8,0x9fd7d0b8]
  ref=0x9fd7d110[0x9fd7d110,0x9fd7d110] lnd=0x9fd7d128[0x9fd7d128,0x9fd7d128]
    LIBRARY OBJECT: object=9ab0ba30
    type=CRSR flags=EXS[0001] pflags=[0000] status=VALD load=0
    CHILDREN: size=16
    child#    table reference   handle
    ------ -------- --------- --------
         0 9ab0b930  9aaf34c0 9fd7ceb0
  BUCKET 104103 total object count=1




好,再列举下x$kglob的重要列的含义
X$kglob 表说明如下:
Kglhdadr (children address) LIBRARY OBJECT HANDLE: handle
Kglhdpar (parent address) LIBRARY OBJECT HANDLE:handle
Kglnaown 依赖object的owner name
Kglnahsh sql的hash value (v$sql 中的hash_value)
Kglnahsv sql 的hash value (长串格式:9a5fb5d584eb42ce5f55b9c92930cf55)
Kglhdobj LIBRARY OBJECT: object
Kglobhd0 data#=0 的 heap 地址
Kglobhd1
Kglobhd2
Kglobhd3..7




 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9240380/viewspace-1843316/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9240380/viewspace-1843316/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值