一、保留區
沒有被PIN住大對象的載入、老化將會使共用池產生片段,Oracle想了個方法解決這個問題,它專門在共用池開闢一塊地區,所有大小超過4400位元組的對象,將在此專門開闢的地區中分配空間,這塊地區被稱為保留區。這樣,讓大對象和小對象分開儲存,可以減少大對象的載入、老化以大量小對象產生的影響,並且可以減少小對象地區內的記憶體片段。而且Oracle針對保留區設計了專門的記憶體管理演算法,使得大對象可以更快速的載入。
你可以使用shared_pool_reserved_size參數設定此保留區的大小,預設情況下,保留區將被自動化佈建為共用池大小的5%。另外,保留區大小不能設定為超過共用池大小的一半,否則將會報出錯誤。通常情況下,保留區的大小保留預設值就行,我們一般不需要調節它。
關於進入保留區對象的大小,Oracle更不建議我們調節它。但有時4400這個值對我們的系統可能並不合適。假設經常4000位元組左右(不到4400)的對象被載入到共用池中,三、四KB的對象,已經是大對象了,並且這些大對象很少使用,這樣將它們PIN在記憶體中有點浪費空間,不到4400的大小使得它們無法被載入到保留區,這些對象每次執行時的載入需要老化很多小對象,並且還很容易造成共用池的片段。這時,我們可以調低4400這個限制值,比如我們可以將保留區的限制降到3500,這樣可以讓那些本來不能進入保留區的對象可以進入保留區。這不旦可以加快這些對象的載入速度,重要的是減少了它們對眾多小對象的影響。我們可以通過V$DB_ OBJECT_CACHE觀察對象在共用池中所佔用的記憶體大小,如果發現上述情況,可以調低4400這個限制值。這個限制是用一個隱藏參數來設定的:_shared_pool_reserved_min_alloc。凡是參數名前帶有底線的,都被稱為隱藏參數,這些隱藏參數不能通過Show parameter顯示,我們可以使用我寫的指令碼Show_para.sql顯示隱藏參數和它們的意義,此指令碼的編寫見本章末尾的附錄部分。
有一個視圖可以用來協助調節保留區:V$SHARED_POOL_RESERVED,它有如下的列:
FREE_SPACE:保留區中自由空間的總和
AVG_FREE_SIZE:每個自由記憶體塊的平均大小
FREE_COUNT:自由的記憶體塊數量
MAX_FREE_SIZE:最大的自由記憶體塊大小
USED_SPACE:保留區中已使用的空間大小
AVG_USED_SIZE:每個已經使用的記憶體塊的平均大小
USED_COUNT:已使用的記憶體塊數量
MAX_USED_SIZE:已使用的最大的記憶體塊大小
REQUESTS:在保留區中搜尋自由記憶體塊的次數
REQUEST_MISSES:保留區中沒有可以滿足要求的記憶體塊並開始在保留區中LRU鏈中重新整理對象的次數
LAST_MISS_SIZE:最後一次出現REQUEST_MISSES時,所請求的空間大小
MAX_MISS_SIZE:最大一次出現REQUEST_MISSES時,所請求的空間大小
下面的列即使SHARED_POOL_RESERVED_SIZE沒有被設定也是有效:
REQUEST_FAILURES:無論保留區還是非保留區,沒有可以滿足要求的記憶體的次數(也就是ORA-4031錯誤發生的次數)
LAST_FAILURE_SIZE:最後一次REQUEST_FAILURES時所請求的記憶體大小
後三列相關DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD過程。
ABORTED_REQUEST_THRESHOLD:最小的超過DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD設定值的大小
ABORTED_REQUESTS:超過DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD的次數
LAST_ABORTED_SIZE:最後一次超過DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD時的大小。
注意,如果REQUEST_FAILURES大於0且持續增加時,說明使用者要求大小為N的記憶體塊,但共用池內已經沒有大小超過N的記憶體塊。當REQUEST_FAILURES增加的比較快時,使用者的操作將會失敗並收到著名的ORA-04031錯誤,就是“共用池記憶體不足”,通常還有一句“不能申請大於N位元組的記憶體塊”。
造成這種情況有三種原因,一是記憶體的確不足了,這個時候你要增加記憶體。二是共用池中還有記憶體,但都是小塊,沒有大小超過N位元組的記憶體塊以滿足使用者的請求,也就是說記憶體中有片段了。關於共用池記憶體片段的解決方案,我們馬上就說。再來看第三種情況,三是共用池中還有記憶體,但因為保留區設定的不合理,使用者要在普通區中請求記憶體(使用者請求的記憶體大小未超過4400),而普通區中已經沒有自由記憶體了,但保留區中還有很多空閑。或者情況相反,使用者在保留區中請求記憶體,保留區記憶體已經不足,但普通區中仍有大量記憶體空餘。
當4031錯誤出現時,你的情況是否屬於第三種―――保留設定不合理,可以通過本節所介紹的視圖得知。下面我們分別介紹一下普通區空間不足和保留區空間不足這兩種情況的監測和解決:
(一) 、普通區記憶體空間不足:
REQUEST_FAILURES不為0且持續增加時,如果LAST_FAILURE_SIZE < _SHARED_POOL_RESERVED_MIN_ALLOC(進入保留區的對象最小大小限制),例如,_SHARED_POOL_RESERVED_MIN_ALLOC限制仍是預設值4400,而LAST_FAILURE_SIZE是3800,也就是最後一次使用者請求記憶體失敗時使用者所請求的記憶體大小為3800位元組。3800小於4400,這說明使用者是在普通區中請求記憶體失敗的。觀察一下保留區記憶體是否充足,如果充足的話,可以將_SHARED_POOL_RESERVED_MIN_ALLOC設定的小於3800讓使用者的請求在保留區內分配,或才乾脆減少保留區大小,這樣普通區中空間自然就會多起來。那麼,如果確定保留區中記憶體是否充足呢?可以通過下面這些列進行觀察:
Ÿ FREE_SPACE:保留區中自由空間的總和
Ÿ AVG_FREE_SIZE:每個自由記憶體塊的平均大小
Ÿ FREE_COUNT:自由的記憶體塊數量
Ÿ MAX_FREE_SIZE:最大的自由記憶體塊大小
Ÿ USED_SPACE:保留區中已使用的空間大小
Ÿ AVG_USED_SIZE:每個已經使用的記憶體塊的平均大小
Ÿ USED_COUNT:已使用的記憶體塊數量
Ÿ MAX_USED_SIZE:已使用的最大的記憶體塊大小
如果FREE_SPACE顯示的自由空間還有很多,就說明保留區中仍有大量空間,完全可以將_SHARED_POOL_RESERVED_MIN_ALLOC設定的小一些,或減少保留區所佔記憶體。
如果保留區中空間也不是太足了,就需要檢查共用池中是否片段太多,如果不是片段的問題,就只有增大共用池大小了。關於片段我們馬上就討論。
(二) 、保留區空間不足
當REQUEST_FAILURES不為0且持續增加時,LAST_FAILURE_SIZE > _SHARED_POOL_RESERVED_MIN_ALLOC,就說明使用者所請求的記憶體要在保留區中分配,而保留區這時的空間已經不足已滿足使用者的請求了。
這時我們可以加大_SHARED_POOL_RESERVED_MIN_ALLOC的限制值,減少進入保留區的對象數。將SHARED_POOL_RESERVED_SIZE參數的值設大一些,以增加保留區大小。當然,如果你的主機上仍有空餘記憶體,也可以增大共用池記憶體大小。