深入理解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/31444259/viewspace-2136195/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 深入理解shared pool共享池之library cache系列一
- 深入理解shared pool共享池之library cache系列二
- 深入理解shared pool共享池之library cache的library cache lock系列四
- 深入理解shared pool共享池之library cache的library cache pin系列三
- 共享池之六:shared pool latch/ library cache latch /lock pin 簡介
- SHARED POOL 空閒空間分配流程
- Shared pool的library cache lock/pin及硬解析
- 基於引數shared_pool_reserved_size進一步理解共享池shared pool原理
- zt_Oracle shared pool internals_共享池_shared_poolOracle
- 等待模擬-library cache shared pool 硬解析
- 優化Shared Pool Latch與Library Cache Latch競爭優化
- shared pool library cache latch 競爭優化辦法優化
- 共享池之五:Shared Pool子池與結果集快取技術快取
- shared pool之三:library cache結構/library cache object的結構-dump LibraryHandleObject
- zt_eygle大師_shared pool共享池管理機制系列文章
- Shared pool深入分析及效能調整(一)
- Flush an Object Out The Library Cache [SGA] Using The DBMS_SHARED_POOLObject
- Shared Pool優化和Library Cache Latch衝突優化優化
- 【每日一摩斯】-Shared Pool優化和Library Cache Latch衝突優化 (1523934.1)-系列6優化
- 【每日一摩斯】-Shared Pool優化和Library Cache Latch衝突優化 (1523934.1)-系列5優化
- 【每日一摩斯】-Shared Pool優化和Library Cache Latch衝突優化 (1523934.1)-系列4優化
- 【每日一摩斯】-Shared Pool優化和Library Cache Latch衝突優化 (1523934.1)-系列3優化
- 【每日一摩斯】-Shared Pool優化和Library Cache Latch衝突優化 (1523934.1)-系列2優化
- 【每日一摩斯】-Shared Pool優化和Library Cache Latch衝突優化 (1523934.1)-系列1優化
- 深入淺出buffer cache和shared pool記載01
- 深入淺出cache buffer和shared pool記載02
- 深入淺出buffer cache和shared pool記載03
- 資料庫體系結構-共享池(shared pool),largepool,Java池,流池資料庫Java
- oracle調優之-共享池尺寸調優+library cache+dicitonary library 命中率Oracle
- 使用DBMS_SHARED_POOL包將物件固定到共享池物件
- 共享池的調整與優化(Shared pool Tuning)優化
- 故障排除:Shared Pool優化和Library Cache Latch衝突優化優化
- Shared pool深入分析及效能調整
- 理解Oracle Shared PoolOracle
- latch:shared pool的一點理解
- shared_pool——解決ORA-4031錯誤
- 深入理解Java併發框架AQS系列(四):共享鎖(Shared Lock)Java框架AQS
- Shared pool深入分析及效能調整(二)