国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

Oracle內存結構(二)----Shared Pool的詳細信息

2024-08-29 13:44:56
字體:
來源:轉載
供稿:網友

  
The Shared Pool

 

The Shared Pool在SGA中是SIZE較大的一個部分.有很多DBA沒搞明白Shared Pool是用來做什么的,不知道怎么定Shared Pool的合適的SIZE.就隨意的將它的SIZE搞得很大.有時候可能是不夠大,但更多的時候是在浪費內存空間.而且太大的Shared Pool會影響性能.

 

塊(Chunk):

要更好的理解Shared Pool,得對X$KSMSP表多做點研究.這個表中的每一個記錄行對應的是Shared Pool內存中的一個Chunk(塊).

SQL> select ksmchcom, ksmchcls, ksmchsiz from x$ksmsp;

KSMCHCOM           KSMCHCLS KSMCHSIZ

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

KGL handles       recr 496

PL/SQL MPCODE     recr 1624

dictionary cach   freeabl 4256

free memory        free 1088

library cache      freeabl 568

library cache      recr 584

multiblock rea     freeabl 2072

permanent memor    perm 1677104

row cache lru      recr 48

session param v    freeabl 2936

sql area            freeabl 2104

sql area            recr 1208

上面的是對這個表查詢的例子.(對整個表的查詢有5726行左右的記錄)

在每個Shared Pool Chunk已經分配好之后,代碼將語句轉化并使其有作用的這一過程實際上就稱為一次分配.這個語句可以在X$KSMSP表中的KSMCHCOM字段看到,描述分配的內存Chunk.每一個Chunk都要比它所包含的對象要大,因為每個Chunk都有多出來16字節的頭信息用于存儲確認Chunk的類型、類別和大小SIZE還有用于Shared Pool治理的鏈接指針.

內存Chunk主要有四種類別,可以從X$KSMSP表中的KSMCHCLS看到.

   free:這種類別的Chunk稱為Free Chunk.它不包含有效的對象,可以自由分配.

   recr:可重建的Chunk(Recreatable Chunk),這種Chunk有包含對象,而這些對象在必要的時候是可以臨時被刪除并在有需要的情況下進行重建.一個例子,包含Shared SQL Statements的Chunks就可以重建

freeabl:可釋放的Chunk(Freeabl Chunk),這種Chunk也有包含對象,這些對象在一個session的生存期間是經常可用的而在session斷掉之后就不可用.這些Chunks可以在session斷開之前進行釋放,可以部分釋放也可以全部釋放.Freeable Chunk是不能臨時被刪除的,因為它是不可重建的.

perm:永久性的內存Chunk(Permanent memory Chunk).它包含的對象是不能被釋放的,是永久存在于內存中的.一些大的永久性的內存Chunk內部也包含一定量的free space.可以根據需要釋放給shared poo.

select

  ksmchcom  contents,

  count(*)  chunks,

  sum(decode(ksmchcls, 'recr', ksmchsiz))  recreatable,

  sum(decode(ksmchcls, 'freeabl', ksmchsiz))  freeable,

  sum(ksmchsiz)  total

from

  sys.x_$ksmsp

where

  inst_id = userenv('Instance') and

  ksmchcls not like 'R%'

group by

  ksmchcom

 

KSMCHCOM  
         CHUNKS      RECR        FREEABL     TOTAL

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

KGFF heap          6           1296         2528        3824

KGK contexts      2                       2400         2400

KGK heap          2          1136                     1136

KGL handles       571        178616                178616

KQLS heap         404        87952      524888      612840

PL/SQL DIANA      274        42168      459504      501672

PL/SQL MPCODE     57         14560      88384       102944

PLS cca hp desc   1                    168         168

PLS non-lib hp    1          2104                   2104

character set m   5                    23504       23504

dictionary cach   108                  223872      223872

fixed allocatio   9          360                   360

free memory       185                              614088

kzull             1             
       48          48

library cache     1612       268312     356312      624624

multiblock rea    1                     2072        2072

permanent memor   1                                1677104

reserved stoppe   2                                48

row cache lru     24         1168                  1168

session param v   8                    23488       23488

sql area          983        231080     1303792     1534872

table columns     19         18520                 18520

table definiti    2          176                   176

上面這個查詢可以得到Shared Pool中所有Chunks的類型,類別和大小SIZE等相關信息.上面只列出部分記錄.

 

Free Lists:

Shared Pool中的Free Chunks,于它們的大小為基準被組織成Free Lists或者BUCkets.下面的一張表是Bucket號和Free Chunks SIZE的對應關系:

 

 



用下面這個腳本可以查詢到Chunks數和每個Free List中的Free Space量.

select

  decode(sign(ksmchsiz - 80), -1, 0, trunc(1/log(ksmchsiz - 15, 2)) - 5)

    bucket,

  sum(ksmchsiz)  free_space,

  count(*)  free_chunks,

  trunc(avg(ksmchsiz))  average_size,

  max(ksmchsiz)  biggest

from

  sys.x_$ksmsp

where

  inst_id = userenv('Instance') and

  ksmchcls = 'free'

group by

  decode(sign(ksmchsiz - 80), -1, 0, trunc(1/log(ksmchsiz - 15, 2)) - 5)

BUCKET      FREE_SPACE FREE_CHUNKS AVERAGE_SIZE BIGGEST

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

0  
         166344    3872         42           72

1           32208      374          86            96

4           928        1            928           928

6           11784      4            2946          3328

 

當一個進程需要Shared Pool Memory分配一個Chunk時,它首先會到Free Lists中查找與它所需的SIZE匹配的Chunk.假如跟所需的SIZE沒有確切相符的Chunk可以分配則會繼續在Free Lists中尋找一個更大的Chunk.假如找到的Chunk有24字節或者更多,則這個Chunk將會被分裂開來使用,將其余的Free Space部分返還到Free Lists中.假如上面的都找不到,則會從一個非空的Free Lists中找一個最小的Chunk給它使用.最后的方式是以LRU機制對Free Lists進行描述

   Free Lists的描述,治理和Chunk的分配都是在Shared Pool Lathes的保護下進行的.假如Shared Pool包含有大量的小的Free Chunks時,在對這個非凡的Free Lists進行描述時,Shared Pool Lathes將會被占有比較長的一段時間.實際上,經常出現的Shared Pool Lathes的競爭和等待就是因為包含了大量的小的Free Chunks.所以增加Shared Pool 的SIZE并不能減少Shared Pool Lathes Contention而且還會使得這個競爭更加嚴重,這就是前面提到的將Shared Pool的SIZE設為很大并不一定會提高性能原因.

  

LRU Lists:

假如一個進程沒辦法從Shared Pool Free Lists中獲得一個Free Chunk,則它會從Shared Pool中刪除一個包含有Recreatable對象的Chunks來釋放足夠大的Chunks滿足自己的使用.

  Recreatable Chunks有兩個種類:一種是Pinned在內存中的,一種是沒有Pinned在內存中的.Pinned在內存中的Chunks跟用DBMS_SHARED_POOL.KEEP執行來KEEP在Shared Pool中是不一樣的. DBMS_SHARED_POOL.KEEP是需要DBA來干預執行的,并且只能放在library cache中.而Pinned Chunks是自動執行的,它在Chunks包含正在使用的對象時就會自動被pinned在Shared Pool中.Pinned Recreatable Chunks是不能釋放空間的,而Unpinned Recreatable Chunks是可以釋放出來的.

  在Shared Pool中,Unpinned Chunks被組織成兩個Lists,它們都是以LRU機制來排列的.分別被稱為臨時的LRU List和循環的LRU List. Chunks在Unpinned時放在MRU(most recently used)的最后面,在它們pinned時將會從這個MRU List中刪除.

  在一個進程需要新分配一部分Shared Pool Memory內存時,Chunks也會從LRU List的最尾端刪除.Chunks以每8個chunks為一個集而被flushed(暫時說為清空)-----首先是從臨時的LRU List,然后再從循環的LRU List. Chunks是在不考慮SIZE的大小并且以LRU機制被flushed的.有一些Chunks是不能被 flushed的,如用DBMS_SHARED_POOL.KEEP執行后的包含library cache 對象的Chunks是不能被 flushed.這些Chunks通過pinned方式來代替被刪除.

  Unpinned Recreatable Chunks兩種類型的LRU Lists: 臨時的LRU List和循環的LRU List的長度可以從fixed表X$KGHLU查詢到,還有已經flush掉的Chunks數,由于pinned和unpinned而加入到LRU List或者是從LRU List刪除的Chunks數.從X$KGHLU表也可以知道LRU Lists被flushed完全但不成功(不理解)的次數和最近一次請求Chunk失敗的所需要Chunk SIZE.具體看下面的語句:

column kghlurcr heading "RECURRENTCHUNKS"

column kghlutrn heading "TRANSIENTCHUNKS"

column kghlufsh heading "FLUSHEDCHUNKS"

column kghluops heading "PINS ANDRELEASES"

column kghlunfu heading "ORA-4031ERRORS"

column kghlunfs heading "LAST ERRORSIZE"

 


select

  kghlurcr,

  kghlutrn,

  kghlufsh,

  kghluops,

  kghlunfu,

  kghlunfs

from

  sys.x_$kghlu

where

  inst_id = userenv('Instance')

/

 

RECURRENT TRANSIENT   FLUSHED     PINS AND    ORA-4031     LAST ERROR

CHUNKS     CHUNKS      CHUNKS      RELEASES     ERRORS       SIZE

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

121         164         148447    4126701      0         0

 

LRU Lists的長度和flush率跟前臺應用和工作流量的變化有很大的依靠關系.長或短的LRU Lists都不會造成問題,但是Chunks flush則在對內存的健康治理中占用很重要的一部分.假如TRANSIENT CHUNKS長于RECURRENT CHUNKS則說明Shared Pool SIZE太大了.而Chunks flush到其它的LRU操作的命中率假如大于1/20則說明Shared Pool SIZE太小.(上面這個是別人的經驗介紹)

 

Spare free memory:

假如一個大的內存請求從Free Lists和LRU Lists Flushing都不能分配,Oracle則會用另外的一種方式來實現.

Oracle的重排序并不是用來接合空閑內存的.當一些Chunks已經被釋放它們將會跟后面的Chunk接合一起使用(這里所謂的接合是前面一個free chunk跟后面一個free chunk接合在一起成為一個更大的free chunk).一般地,Oracle只會在顯示的執行命令ALTER SYSTEM FLUSH SHARED POOL后才會以完全的方式來接合Shared Pool中的free space.即使當Shared Pool有足夠的連續的內存段時,內存請求分配也有可能失敗的.假如空閑內存被分成多個小的Chunks時,也有可能沒法滿足大的內存請求分配.

為了滿足較大的內存請求分配,Oracle用重排序的方式來釋放更多的內存給Shared Pool. 實際上,Oracle在實例啟動的時候只分配大概一半的原Shared Pool SIZE給Shared Pool(即劃分shared_pool_size的一半內存出來給Shared Pool.等以后需要用到更多時再用重排序的方式秋釋放給它).Oracle用這種方式來確保Shared Pool不會產生太多的碎片.

Oracle的多余空閑內存(Spare free memory),在Shared Pool中被隱藏在永久性的內存Chunks(permanent memory chunks)中.這些內存不在Shared Pool的Free Lists中,所以是不能立即被分配出來使用的.在V$SGASTAT可以看到free memory statistics.在有必要的時候Spare Free Memory Chunks才會被釋放給Shared Pool.在這些Spare Free Memory已經被分配完給Shared Pool之后,還有對Shared Pool Memory請求但是分配不到Free Memory,則會產生ORA-4031’unable to allocate x bytes of shared memory’錯誤.假如在數據庫運行于高峰登錄量一段時間之后,Oracle還有剩余較大部分的Spare Free Memory則說明此時所設置的shared_pool_size過大.可以通過下面的腳本查看剩余的Spare Free Memory.

select

  avg(v.value)  shared_pool_size,

  greatest(avg(s.ksmsslen) - sum(p.ksmchsiz), 0)  spare_free,

  to_char(

    100 * greatest(avg(s.ksmsslen) - sum(p.ksmchsiz), 0) / avg(v.value),

    '99999'

  ) '%' wastage

from

  sys.x_$ksmss s,

  sys.x_$ksmsp p,

  sys.v_$parameter v

where

 
s.inst_id = userenv('Instance') and

  p.inst_id = userenv('Instance') and

  p.ksmchcom = 'free memory' and

  s.ksmssnam = 'free memory' and

  v.name = 'shared_pool_size'

/

 

The Reserved List:

  一般,最大的Chunks也不會超過5000bytes的.假如有請求更大的Chunks的話,Oracle用的是另外一種方式,即下面說的Reserved Shared Pool,而不會到Shared Pool Free Lists和LRU Lists中尋找適應的或者更大SIZE的Chunks來給它使用.

Oracle為大的Chunks保留了Shared Pool的一部分.缺省保留的是shared_pool_size的5%.也可以通過參數shared_pool_reserved_size設置其大小.對應參數名,這一部分是從Shared Pool中取出的一部分SIZE.

超過5000bytes的Chunks會被放到Shared Pool的保留部分中,開始是可以通過隱含參數_SHARED_POOL_RESERVED_MIN_ALLOC來設置的,但是在實例啟動之后是不能修改的.所以小的Chunks是不會被放到Shared Pool的保留部分中來的. Shared Pool的保留部分中的Free Memory不被包含在一般的Shared Pool Free Lists中,而是放在一個單獨的Reserved Free List(針對Reserved Shared Pool)中.然而, Reserved Shared Pool是沒有屬于它自己的LRU Lists 來為Unpinned Recreatable Chunks服務的.因此,在為一般的Free Lists釋放內存空間時大的Chunks是不會被flushed(清空)的.而在為Reserved Shared Pool Free Lists釋放內存空間時,小的Chunks是不會被flushed(Reserved Shared Pool Free Lists只有大的Chunks).(這里的大的Chunks我們指的是超過5000bytes的Chunks)

在V$SHARED_POOL_RESERVED視圖我們可以查看Reserved Shared Pool的統計信息.非凡是字段REQUEST_MISSES,它顯示的是從Reserved Shared Pool Free Lists中請求大的Chunks沒有即刻滿足的次數.這個值應當為0.也就是說,在沒有flush Unpinned Recreatable Chunks的情況下在Reserved Shared Pool應該有足夠多的Free Memory來滿足短時間的Freeable memory的請求.查看V$SHARED_POOL_RESERVED視圖中的USED_SPACE字段來確定多大的Reserved Shared Pool SIZE才是適當的.用下面的腳本查看Reserved Shared Pool 的SIZE和HWM以及使用率.最好在關閉數據庫之前做查詢并結合V$RESOURCE_LIMIT查看其它資源的使用.

PRompt Reserved Pool High-Water-Mark Since Instance Startup

prompt ====================================================

 

select

  sum(r.ksmchsiz) - &stopper  reserved_size,

  sum(

    r.ksmchsiz -

    decode(h.kghlunfu, 0, decode(r.indx, 1, r.ksmchsiz, 0), 0)

  ) - &stopper  high_water_mark,

  to_char(

    100 * (sum(

       r.ksmchsiz -

       decode(h.kghlunfu, 0, decode(r.indx, 1, r.ksmchsiz, 0), 0)

     ) - 48

    ) / (sum(r.ksmchsiz) - &stopper),

    '99999'

  ) '%'  "  USAGE"

from

  sys.x_$kghlu  h,

  sys.x_$ksmspr  r

where

  h.inst_id = userenv('Instance') and

  r.inst_id = userenv('Instance')

/

prompt

 

RESERVED_SIZE HIGH_WATER_MARK USAGE

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

256000        15080           6%

 


Marking Objects for Keeping:

在一個SIZE適當的SHARED POOL, dead Chunks是不會被清除出去的.任何一個清除的動作都意味著一些有用的對象也會被清除掉的危險.非凡是可重建的對象,因為它們只在一定時間內才被使用,但是在它們被重建時的代價可能會很大,因為它們可能是一個很大的對象或者需要更復雜的處理進程.

  減輕這個危險性的辦法就是用DBMS_SHARED_POOL.KEEP將一些用戶自己認為有用的對象KEEP到SHARED POOL中.這個程序將對象以及有關的下級對象放在library cache中并將它們標志為是KEEP在SHARED POOL中的.所以最合適做這個的時間是在實例啟動之后做KEEP操作以免SHARED POOL產生更多的碎片.經常會錯誤的認為如包等大的對象不需要KEEP到SHARED POOL中,因為它們一般會被放到SHARED POOL的RESERVED部分,因此被清除的機率非常小.其實不然,很多大的對象實際上是以多個小的Chunks來分配SHARED POOL內存的,是沒辦法以它們的大小來獲得非凡的保護.通過查看表X$KSMLRU可以確認哪些library cache對象需要KEEP到SHARED POOL中.

 

Flushing the Shared Pool:

接合連續的free chunks的唯一方法就是用命令ALTER SYSTEM FLUSH SHARED POOL顯示的清空SHARED POOL.在實踐中,清空SHARED POOL會減少shared pool latch競爭,也會降低產生ORA-4031錯誤機率,也會減少即刻的性能競爭,非凡是那些被KEEP到SHARED POOL中的主要對象.反之,假如那些主對象都已經KEEP到SHARED POOL中了,而且你的SHARED POOL SIZE比較適當,就要少使用FLUSH SHARED POOL,否則,實例將會在正常的運行時間對系統性能的要求非凡大.

一般地,會在晚上備份完之后來做FLUSH SHARED POOL.其它的時間就是在SHARED POOL有很多的碎片或者空間不足.在做FLUSH SHARED POOL時要確認不要對CAHED SEQUENCE產生不必要的缺口.要達到這個目的可以將SEQUENCE KEEP到SHARED POOL中,假如是單個實例也可以臨時的執行ALTER SEQUENCE NOCACHE.可用下面的PROCEDURE來確認哪些SEQUENCE需要KEEP到SHRAED POOL中.假如需要做SHUTDOWN ABORT來關閉數據庫時最好先將SEQUENCE KEEP到SHARED POOL中.

declare

  cursor cached_sequences is

    select

      sequence_owner,

      sequence_name

    from

      sys.dba_sequences

    where

      cache_size > 0;

  sequence_owner varchar2(30);

  sequence_name varchar2(30);

begin

  open cached_sequences;

  loop

    fetch cached_sequences into sequence_owner, sequence_name;

    exit when cached_sequences%notfound;  

    sys.dbms_shared_pool.keep(sequence_owner '.' sequence_name, 'Q');

  end loop;

end;  

/

Heaps and Subheaps

針對SHARED POOL的FIXED TABLES X$是以KSM和KGH開頭,它們分別代表的意思是Oracle內存治理器和堆治理器模型.兩者是緊密聯系在一起工作的.內存治理器是負責與操作系統OS進行交互以獲得內存供Oracle使用和內存分配信息.堆治理器則是進行動態的內存分配和治理.SHARED POOL也叫SGA HEAP就是這個原因了.

一個堆包含堆描述器和一個或多個內存區,當然也包含子堆.在這種情況下,子堆的堆描述器和內存區是以父堆的Chunks來分配的.HEAP的大小是以HEAP的類型和HEAP’S FREE LIST和LRU LIST的LIST頭信息的不同而不同的.每個內存區都有頭部信息指向前面的和后面的一個堆,還有此HEAP還有多少空間可分配的信息.

除了Reserved部分,SHARED POOL的子堆實際上跟SHARED POOL本身有相同的結構.內存是以Chunks分配的,Free Chunks被組織成Free Lists. Unpinned Recreatable Chunks也是被組織成兩個LRU LISTS: Transient chunks和Recurrent chunks.子堆也有永久性的內存Chunks.也可以再包含子堆,深度為4.

CACHED在SHARED POOL的大部分對象實際上都是在子堆里面為一個新的Chunks查找空間,就好象是SHARED POOL自己為一個新的Chunks查找空間.所不同的是,子堆是以區來增長的,而SHARED POOL是一個固定大小的SIZE.子堆新區是以最小SIZE的區(適合對象的Chunks的最小SIZE)來分配的,所以它一般會找最小的Chunks.

 


The Large Pool:

  假如參數LARGE_POOL_SIZE有設置,則Large Pool將會在SGA中的變量區域(variable area)被配置為一個單獨的堆.它不是SHARED POOL的一部分,是以large memory latch來保護的. Large Pool只包含空閑的Chunks和可釋放的Chunks.不包含Recreatable Chunks,所以堆治理器的LRU機制是不被使用的.

  為了阻止在Large Pool中產生碎片,所有的Large Pool Chunks的SIZE一般都以參數_LARGE_POOL_MIN_ALLOC做為其SIZE,其缺省值為16K.這個參數不必要做調優.

  在下列情況下建議你設置LARGE_POOL_SIZE參數使用Large Pool:

       使用了MTS

       使用了Recovery Manager(RMAN)

       使用了并行的查詢選項Parallel Query Option(PQO)

 

 

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泽普县| 泰兴市| 大石桥市| 柘荣县| 沛县| 吴旗县| 汕头市| 宣威市| 屏东市| 桃园市| 江达县| 米易县| 郧西县| 工布江达县| 久治县| 慈溪市| 荣昌县| 呼图壁县| 曲水县| 上蔡县| 苍梧县| 乌鲁木齐县| 罗田县| 德江县| 博野县| 东宁县| 抚顺县| 平湖市| 炎陵县| 通榆县| 鹤岗市| 额敏县| 綦江县| 时尚| 梧州市| 射洪县| 墨江| 衡东县| 信阳市| 边坝县| 嘉峪关市|