深入淺出buffer cache和shared pool記載03

dotaddjj發表於2011-12-15

還是繼續整理eygle深入淺出中關於shared pool部分。

Shared pool共享池,初步僅僅只是理解為sqlpl/sql 資料字典的共享區,提供程式碼共享,當然這也是shared pool最重要的地方。在oracle 10G後的自動sga管理,shared pool回由oracle自動管理,並不需要dba過多的設定,因為系統的業務情況也是不穩定的,buffer cacheshared pool的需求程度也不同,自動sga的管理可以按系統負載情況均衡sga的各個元件。

Alter system set events ‘immediate trace name heapdump leval 2’

EXTENT 8 addr=28000000

Chunk 28000038 sz= 24 R-freeable "reserved stoppe"

Chunk 28000050 sz= 212888 R-free " "

Chunk 28033fe8 sz= 24 R-freeable "reserved stoppe"

Chunk 28034000 sz= 3491192 perm "perm " alo=3491192

Chunk 28388578 sz= 474392 perm "perm " alo=474392

Chunk 283fc290 sz= 14352 perm "perm " alo=14352

Chunk 283ffaa0 sz= 1376 free " "

EXTENT 9 addr=28800000

Chunk 28800038 sz= 24 R-freeable "reserved stoppe"

Chunk 28800050 sz= 212888 R-free " "

Chunk 28833fe8 sz= 24 R-freeable "reserved stoppe"

Chunk 28834000 sz= 3917776 perm "perm " alo=3917776

Chunk 28bf07d0 sz= 56176 perm "perm " alo=56176

Chunk 28bfe340 sz= 6160 perm "perm " alo=6160

Chunk 28bffb50 sz= 1200 free " "

Total heap size = 41942480

FREE LISTS:

Bucket 0 size=16

Bucket 1 size=20

Bucket 2 size=24

Bucket 3 size=28

Bucket 4 size=32

Bucket 5 size=36

Bucket 6 size=40

Bucket 7 size=44

Bucket 8 size=48

Bucket 9 size=52

……擷取部分內容,其中oracle10G的,版本不同shared pool的管理bucket演算法不同

Shared pool透過free list管理free記憶體塊(chunk),free的記憶體塊(chunk)按不同的size被劃分到不同部分bucket進行管理,感覺有點像buffer cachebucket了!

資料庫啟動時,shared pool是連續記憶體塊,但是當空間分配使用後,記憶體塊開始被分割,碎片出現,bucket列表變長。

oracle請求shared pool空間時,首先進入相應bucket進行查詢,找不到,則轉向下一個非空的bucket,獲取chunk後,分割這個chunk,剩餘部分會進入相應bucket進一步增加碎片,最終是由於不停分割chunk,導致每個bucket的記憶體塊越來越多,越來越小,而bucket 0最為嚴重(一般都是bucket 0的記憶體請求),碎片過多其實也就是相應的bucket上管理的細小的記憶體塊過多,導致shared pool效能產生的根本原因。

細小記憶體塊過多,導致oracle收索shared pool空閒記憶體塊時間過長,收索free list時間過長,根據cache buffer的內容cache buffer lru是管理cache buffer中的lru連結串列收索空閒記憶體和管理lru連結串列,就需要獲得該連結串列的latch,同樣shared poolfree list連結串列也需要獲得該連結串列的latch,也就是shared pool latch,而latchoracle資料庫內部低階鎖,序列機制保證記憶體結構不被併發更新修改所損壞,雖然latch獲取和釋放都非常短(微秒級),但是繁忙的生產庫latch的序列機制往往成為資料庫的極大效能瓶頸。

Oracle 9I中,為了增加大共享池支援,shared pool latch從原來的一個增加到現在的7個。這一點可以查詢檢視v$latch_children驗證。在oracle 9I後,由於shared pool的相應bucket演算法改變,shared pool latch數量的增加,大共享池已經可以很大程式的提高資料庫的效能,而不用過多的擔心而帶來的管理的消耗。

SQL> col name format a15;

SQL> select addr,name,gets,misses,spin_gets from v$latch_children where name='shared pool';

ADDR NAME GETS MISSES SPIN_GETS

-------- --------------- ---------- ---------- ----------

056BCECC shared pool 518465 145 143

056BCF34 shared pool 9 0 0

056BCF9C shared pool 9 0 0

056BD004 shared pool 9 0 0

056BD06C shared pool 9 0 0

056BD0D4 shared pool 9 0 0

056BD13C shared pool 9 0 0

7 rows selected

深入淺出中還提到,如果os4個或4個以上cpu,並且shared pool大於250MBoracle會把shared pool分割為多個子緩衝池進行管理,每個子緩衝池都擁有獨立結構,LRUshared pool latch。(不過自己暫時還沒有辦法驗證該結論)子緩衝的數量由隱含引數_kghdsidx_count控制,該引數_kghdsidx_count預設值為1.

Shared pool的空閒分配和使用情況還可以用檢視x$ksmsp,也就是Kernal Storage Memory Management Sga Heap,其中每一行代表著shared pool中的一個chunk

Ksmchcom:註釋欄位,相應的有free memorysql areaPL/SQL DIANA

Ksmchsiz:記憶體塊大小

Ksmchcls:代表型別, recr包含可以被臨時移出記憶體物件,在需要時可以這個物件可以被重建 free 不包含任何物件的chunkfreeabl 這部分記憶體可以被部分釋放或全部釋放,某些中間過程產生的物件不能被臨時移出記憶體 perm 永久物件,不能被釋放

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

COUNT(*)

----------

29932

SQL> select count(*) from dba_objects where rownum<10;

COUNT(*)

----------

9

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

COUNT(*)

----------

29939

可以看出由於shared pool中進行了sql解析,請求相應的free list上的bucket空間,分割chunk,導致產生了更細碎的記憶體chunk,如果資料庫中存在大量的硬解析,會大量請求shared poolfree listfree空間,同樣在收索free list中會佔用shared pool latch,可能會產生shared pool latch競爭,也會產生更細更小的記憶體碎片,chunk也會增加,導致以後再次請求free記憶體時搜尋free list的變長,又會產生shared pool latch競爭,影響資料庫效能。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25362835/viewspace-1056852/,如需轉載,請註明出處,否則將追究法律責任。

相關文章