Oracle記憶體分配中的子池(Subpool)--ORA-04031
Oracle記憶體分配中的子池(Subpool)--ORA-04031
在 Oracle 9i 和之後的版本,共享池可以被劃分為子池。每個子池是一個小號的共享池,有它自己的空閒列表,記憶體結構條目,和LRU列表。這是一個對共享池和大池的可擴充套件性的改變,現在每一個子池都由一個 child latch 來保護,因此可以增加這些池的吞吐量。這意味著不再有之前版本的對於共享池和大池的單獨 latch 的競爭。共享池中的保留區域也被平均的劃分到每個子池中。
當你遇到 ora-04031 時,trace 會顯示錯誤發生在哪個子池中。
例如:
ORA-04031: unable to allocate 4192 bytes of shared memory ("shared pool","SELECT /*+ FIRST_ROWS */ * F...","sql area (6,0)","kafco : qkacol"):4031:375:2008:ocicon.c
這個例子中,錯誤發生在第六個子池中。
使用子池的缺點是,有些情況下,個別子池被過分利用了。一旦子池選定,即使其他子池有合適的可用記憶體,記憶體塊的搜尋也可能失敗。從 10g 開始,我們確實有這樣的功能,允許當記憶體請求在選定的子池中無法滿足時,“交換”到其他子池進行搜尋,但這功能不可能對所有的記憶體結構和元素都起作用。
注意:有一小部分功能會跨子池的利用記憶體塊。換句話說,就是跨越多子池的條帶化使用記憶體。
這極少有文件記錄,一般來說,記憶體請求會以輪轉的方式,從一個“隨機”的子池中找到它需要的記憶體塊。
不平衡的使用子池會導致 ORA-04031。常見的是在"session param values"記憶體結構上的記憶體分配失敗。在 9i 及更高版本,需要為每個配置了的 process 分配記憶體來儲存動態引數。在啟動時,會選中一個子池來管理所有的"session param values"條目。如果 PROCESSES 引數設定的非常高,並且又沒有非常高的併發連線,這可能導致在子池中不必要的永久記憶體分配,並且可能引發 ORA-04031 問題。一般來說,擁有多個共享池 latch 所帶來的效能上的改善要超過由於過度利用子池而可能帶來的問題。
終端使用者是看不到子池的。他們被隱藏在共享池和大池的使用下。注意:如果共享池使用子池,只要 LARGE_POOL_SIZE>0,就會自動的在大池中建立子池。
參考(這個問題看上去影響了很多 Bug):
- Subpool imbalance for "session parameters"
我預設有多少子池?
子池的數量計算有一個簡單的演算法。首先,在 9i 中一個子池至少有個 128MB,在 10g 中至少 256MB。第二,系統中每 4 個 CPU 可以有一個子池,最多 7 個子池。子池的數量可以用初始化引數 _kghdsidx_count 明確的控制。沒有引數可以明確控制每個子池的大小。
如果有人在 9i 上配置一個 12 CPU 的系統,300MB 的共享池,Oracle 會建立 2 個子池,每個 150MB。如果共享池大小增大到 500MB,Oracle 會建立 3 個子池,每個 166MB。
因為 128MB(甚至 10g 上的 256MB)子池在很多應用環境中可能偏小,每個子池中的記憶體會傾向於需要增大。沒有引數可以改變子池的最小值。唯一的辦法是在一個固定的共享池大小基礎上減少子池的數量,或者增大共享池使得子池大小增長。 請注意增長共享池大小並不一定增長子池的大小,因為如果系統上有很多 CPU,子池的數量也會增長。
10.2.0.3 及以上的變化:根據 bug 4994956,10g 或更高版本上,演算法是將每個子池增長到 512M。
我應當如何控制使用的子池的數量?
變數 _kghdsidx_count 控制了使用的子池的數量。將這個引數設定為 1 會使共享池的行為回退到 8.1.7 版本。即,一個子池。
或者把這行加入 pfile
注意:子池的建立是在啟動過程中 SGA 建立時發生的。上述的 2 個例子中,資料庫都必須重啟來改變子池的數量。對 _kghdsidx_count 的改變也會改變大池中的子池數量。
當透過 _kghdsidx_count 手動的設定子池的數量的時候,推薦的做法是逐漸的進行改動,監控效能影響,以避免任何劇烈的影響。
相反的的,增加子池的數量而不增加池的整體大小的話,由於子池大小變小,可能導致空間問題。
我們知道,從 9i開始,Shared Pool可以被分割為多個子緩衝池(SubPool)進行管理,以提高併發性,減少競爭。
Shared Pool的每個SubPool可以被看作是一個Mini Shared Pool,擁有自己獨立的Free List、記憶體結構以及LRU List。同時Oracle提供多個Latch對各個子緩衝池進行管理,從而避免單個Latch的競爭(Shared Pool Reserved Area同樣進行分割管理)。SubPool最多可以有7個,Shared Pool Latch也從原來的一個增加到現在的7個。如果系統有4個或4個以上的CPU,並且SHARED_POOL_SIZE大於250MB,Oracle可以把Shared Pool分割為多個子緩衝池(SubPool)進行管理,在Oracle 9i中,每個SubPool至少為128MB。
如果你看到過類似如下資訊,那就意味著你可能遇到了SubPool的問題,如下所示:
Tue Dec 11 17:14:49 2007
Errors in file /oracle/app/admin/ctais2/udump/ctais2_ora_778732.trc:
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","IDX_DJ_NSRXX_P_NSRMCCTAIS2","sga heap(2,0)","library cache")
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","IDX_DJ_NSRXX_P_NSRMCCTAIS2","sga heap(2,0)","library cache")
Tue Dec 11 17:14:51 2007
Errors in file /oracle/app/admin/ctais2/bdump/ctais2_pmon_393248.trc:
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","unknown object","sga heap(2,0)","library cache")
Oracle 9i中多個子緩衝池的結構如圖所示。
子緩衝池的數量受一個新引入的隱含引數_KGHDSIDX_COUNT影響。可以手工調整該引數(僅限於試驗環境研究用),觀察共享池管理的變化,可以透過如下步驟轉儲預設情況以及修改後的Shared Pool,再進行觀察:
alter session set events 'immediate trace name heapdump level 2';
alter system set "_kghdsidx_count"=2 scope=spfile;
startup force;
alter session set events 'immediate trace name heapdump level 2';
以下是概要輸出,注意在前者的跟蹤檔案中,sga heap(1,0)指共享池只存在一個子緩衝,後者則存在sga heap(1,0)以及sga heap(2,0)兩個子緩衝池:
[oracle@jumper udump]$ grep "sga heap" eygle_ora_25766.trc
HEAP DUMP heap name="sga heap" desc=0x5000002c
HEAP DUMP heap name="sga heap(1,0)" desc=0x5001ef0c
[oracle@jumper udump]$ grep "sga heap" eygle_ora_25786.trc
HEAP DUMP heap name="sga heap" desc=0x5000002c
HEAP DUMP heap name="sga heap(1,0)" desc=0x5001ef0c
HEAP DUMP heap name="sga heap(2,0)" desc=0x50023c04
子緩衝池的分配的很簡單:
l 每個子緩衝池必須滿足一定的記憶體約束條件;
l 每4顆CPU可以分配一個子緩衝池,子緩衝池的數量最多7個。
在Oracle 9i中,每個SubPool容量至少128MB,而在Oracle 10g中,每個子緩衝池至少為256MB。如前所述,SubPool的數量可以透過_kghdsidx_count引數來控制,但是沒有引數可以顯式地控制SubPool的大小。
根據以上規則,在一個12顆CPU的系統中,如果分配容量為300MB的Shared Pool,Oracle 9i將建立兩個SubPool,每個容量大約150MB,如果共享池容量增加到500MB,Oracle將建立3個SubPool,每個大約166MB。
不管Oracle 9i中的128MB以及Oracle10g中的256MB,這樣的SubPool在許多複雜的系統中,都可能是過小的,在這些情況下,可能要增大SubPool。可以透過控制Shared Pool大小以及SubPool的數量來改變SubPool的大小。一些Bug以及內部表明500MB的SubPool可能會帶來更好的效能,所以從Oracle 11g開始,每個SubPool至少為512MB。
除大小控制之外,在Oracle 10g中,Oracle仍然對共享池的管理做出了進一步改進,那就是對單個子緩衝池進行進一步的細分。現在預設,Oracle 10g會將單個緩衝池分割為4個子分割槽進行管理(這可能是因為通常4顆CPU才分配一個SubPool),使用類似如上的方法在Oracle 10gR2中進行測試:
alter session set events 'immediate trace name heapdump level 2';
alter system set "_kghdsidx_count"=2 scope=spfile;
startup force;
alter session set events 'immediate trace name heapdump level 2';
分析得到的日誌,當僅有一個子緩衝池時,Shared Pool被劃分為sga heap(1,0)~sga heap(1,3)共4個子分割槽:
[oracle@eygle udump]$ grep "sga heap" eygle_ora_13577.trc
HEAP DUMP heap name="sga heap" desc=0x2000002c
HEAP DUMP heap name="sga heap(1,0)" desc=0x2001b550
HEAP DUMP heap name="sga heap(1,1)" desc=0x2001c188
HEAP DUMP heap name="sga heap(1,2)" desc=0x2001cdc0
HEAP DUMP heap name="sga heap(1,3)" desc=0x2001d9f8
當使用兩個子緩衝池時,Shared Pool則被劃分為8個子分割槽進行管理如下:
[oracle@eygle udump]$ grep "sga heap" eygle_ora_13618.trc
HEAP DUMP heap name="sga heap" desc=0x2000002c
HEAP DUMP heap name="sga heap(1,0)" desc=0x2001b550
HEAP DUMP heap name="sga heap(1,1)" desc=0x2001c188
HEAP DUMP heap name="sga heap(1,2)" desc=0x2001cdc0
HEAP DUMP heap name="sga heap(1,3)" desc=0x2001d9f8
HEAP DUMP heap name="sga heap(2,0)" desc=0x20020640
HEAP DUMP heap name="sga heap(2,1)" desc=0x20021278
HEAP DUMP heap name="sga heap(2,2)" desc=0x20021eb0
HEAP DUMP heap name="sga heap(2,3)" desc=0x20022ae8
Oracle 10g中多緩衝池結構如圖所示。
透過一個內部表X$KGHLU([K]ernel [G]eneric memory [H]eap manager State of [L]R[U] Of Unpinned Recreatable chunks)可以查詢這些子緩衝池的分配:
SQL> select addr,indx,kghluidx,kghludur,kghluops,kghlurcr from x$kghlu;
ADDR INDX KGHLUIDX KGHLUDUR KGHLUOPS KGHLURCR
-------- ---- ---------- ---------- ---------- ----------
B5F4C5B4 0 2 3 12773 257
B5F4C1AC 1 2 2 43675 1042
B5F4D9C8 2 2 1 18831 1518
B5F4D5C0 3 2 0 0 0
B5F4D1B8 4 1 3 144697 327
B5F4E9E4 5 1 2 483428 1462
B5F4E5DC 6 1 1 6558 982
B5F4E1D4 7 1 0 0 0
8 rows selected.
通過這一系列的演算法改進,Oracle中Shared Pool管理得以不斷增強,較好地解決了大Shared Pool的效能問題;Oracle 8i中,過大Shared Pool設定可能帶來的栓鎖爭用等效能問題在某種程度上得以解決。從Oracle 10g開始,Oracle開始提供自動共享記憶體管理,使用該特性,使用者可以不必顯示設定共享記憶體引數,Oracle會自動進行分配和調整,雖然Oracle為使用者提供了極大的便利,但是瞭解自動化後面的原理對於理解Oracle的執行機制仍然是十分重要的。
雖然多緩衝池技術使Oracle可以管理更大的共享池,但是SubPool的劃分可能也會導致各分割槽之間的協調問題,甚至可能因為記憶體分散而出現ORA-04031錯誤。最常見的問題是某個子緩衝池(SubPool)可能出現過度使用,當新的程式仍然被分配到這個SubPool時,可能會導致記憶體請求失敗(而此時其他SubPool可能還有很多記憶體空間)。
因為子緩衝池存在的種種問題,從Oracle 10g開始,允許記憶體請求在不同SubPool之間進行切換(Switch),從而提高了請求成功的可能(但是顯然切換不可能是無限制的,所以問題仍然可能存在)。
以下是來自客戶系統的一個實際案例,在一個Oracle9i的系統中,經常出現ORA-04031的錯誤,客戶系統的主要配置如下:
SQL> select * from v$version where rownum <2;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
SQL> show parameter cpu_count
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cpu_count integer 48
SQL> select * from v$sga;
NAME VALUE
------------------------------ ----------------
Fixed Size 762240
Variable Size 2600468480
Database Buffers 18975031296
Redo Buffers 6578176
我們檢查其引數設定,預設的子池設定是7個,程式碼如下:
SQL> select a.ksppinm, b.ksppstvl from x$ksppi a, x$ksppsv b
where a.indx = b.indx and a.ksppinm = '_kghdsidx_count';
KSPPINM KSPPSTVL
---------------------------------------------------------------- --------------------
_kghdsidx_count 7
7個子池都被使用,其Latch使用情況如下:
SQL> select child#, gets from v$latch_children
where name = 'shared pool' order by child#;
CHILD# GETS
---------- ----------
1 333403016
2 355720323
3 273944301
4 197980497
5 282347697
6 354398593
7 468809111
看一下具體的子池使用及記憶體情況,注意到各個Shared Pool子池平均分配了320MB記憶體左右,共享池合計約2256MB:
SELECT 'shared pool (' || NVL (DECODE (TO_CHAR (ksmdsidx), '0', '0 - Unused', ksmdsidx),'Total') || '):' subpool,
SUM (ksmsslen) BYTES, ROUND (SUM (ksmsslen) / 1048576, 2) mb
FROM x$ksmss WHERE ksmsslen > 0
GROUP BY ROLLUP (ksmdsidx) ORDER BY subpool ASC
/
SUBPOOL BYTES MB
------------------------------ ---------- ----------
shared pool (1): 352321536 336
shared pool (2): 335544320 320
shared pool (3): 335544320 320
shared pool (4): 335544320 320
shared pool (5): 335544320 320
shared pool (6): 335544320 320
shared pool (7): 335544320 320
shared pool (Total): 2365587456 2256
8 rows selected.
進一步可以查詢一下各個子池的剩餘記憶體,注意到各個子池剩餘記憶體約在7MB~15MB之間,而這些剩餘記憶體又可能是零散的碎片:
SELECT subpool, NAME, SUM (BYTES), ROUND (SUM (BYTES) / 1048576, 2) mb
FROM (SELECT 'shared pool (' || DECODE (TO_CHAR (ksmdsidx), '0', '0 - Unused', ksmdsidx)
|| '):' subpool, ksmssnam NAME, ksmsslen BYTES
FROM x$ksmss WHERE ksmsslen > 0 AND LOWER (ksmssnam) LIKE LOWER ('%free memory%'))
GROUP BY subpool, NAME ORDER BY subpool ASC, SUM (BYTES) DESC
/
SUBPOOL NAME SUM(BYTES) MB
------------------------------ ------------------------------ ---------- ----------
shared pool (1): free memory 8158640 7.78
shared pool (2): free memory 7414472 7.07
shared pool (3): free memory 7831608 7.47
shared pool (4): free memory 10690992 10.2
shared pool (5): free memory 17201856 16.4
shared pool (6): free memory 8239920 7.86
shared pool (7): free memory 13925416 13.28
透過以下查詢可以詳細列舉不同子池的Free記憶體塊情況,從輸出可以觀察到,每個子池大於10KB的記憶體塊都很少,這也就意味著,當有大塊的共享記憶體請求時就可能出現ORA-04031錯誤(注意:R-free指保留池的剩餘空間):
SQL> SELECT ksmchidx "SubPool", 'sga heap(' || ksmchidx || ',0)' sga_heap,
2 ksmchcom chunkcomment,
3 DECODE (ROUND (ksmchsiz / 1000),
4 0, '0-1K', 1, '1-2K',2, '2-3K',3, '3-4K',4, '4-5K', 5, '5-6k',
5 6, '6-7k', 7, '7-8k',8, '8-9k',9, '9-10k', '> 10K'
6 ) "size",
7 COUNT (*), ksmchcls status, SUM (ksmchsiz) BYTES
8 FROM x$ksmsp WHERE ksmchcom = 'free memory'
9 GROUP BY ksmchidx, ksmchcls, 'sga heap(' || ksmchidx || ',0)',ksmchcom, ksmchcls,
10 DECODE (ROUND (ksmchsiz / 1000),
11 0, '0-1K', 1, '1-2K',2, '2-3K',3, '3-4K',4, '4-5K', 5, '5-6k',
12 6, '6-7k', 7, '7-8k',8, '8-9k',9, '9-10k', '> 10K' );
SUBPOOL SGA_HEAP CHUNKCOMMENT size COUNT(*) STATUS BYTES
------- ------------------- ---------------- ----- ---------- -------- ----------
1 sga heap(1,0) free memory 0-1K 5173 free 922568
1 sga heap(1,0) free memory 1-2K 5422 free 5274920
.........
1 sga heap(1,0) free memory 6-7k 2 R-free 11968
1 sga heap(1,0) free memory 7-8k 9 R-free 62096
1 sga heap(1,0) free memory 8-9k 12 R-free 95480
1 sga heap(1,0) free memory 9-10k 11 R-free 99192
1 sga heap(1,0) free memory > 10K 25 R-free 434272
2 sga heap(2,0) free memory 0-1K 4919 free 848864
.......
2 sga heap(2,0) free memory 9-10k 5 R-free 46056
2 sga heap(2,0) free memory > 10K 43 R-free 769144
3 sga heap(3,0) free memory 0-1K 6921 free 1058264
。。。。。。
3 sga heap(3,0) free memory 9-10k 9 R-free 81344
3 sga heap(3,0) free memory > 10K 64 R-free 1212424
4 sga heap(4,0) free memory 0-1K 6430 free 928688
.......
4 sga heap(4,0) free memory 9-10k 9 R-free 80464
4 sga heap(4,0) free memory > 10K 34 R-free 689640
5 sga heap(5,0) free memory 0-1K 4416 free 779096
......
5 sga heap(5,0) free memory 9-10k 4 R-free 36344
5 sga heap(5,0) free memory > 10K 40 R-free 1669384
6 sga heap(6,0) free memory 0-1K 6203 free 863104
。。。。。。
6 sga heap(6,0) free memory 9-10k 11 R-free 99464
6 sga heap(6,0) free memory > 10K 56 R-free 1758912
7 sga heap(7,0) free memory 0-1K 3814 free 607616
......
7 sga heap(7,0) free memory 9-10k 6 R-free 54432
7 sga heap(7,0) free memory > 10K 52 R-free 2816480
120 rows selected.
針對這種情況,我們可以相應減少Shared Pool子池的數量,以使得每個子池可以有足夠的空閒記憶體可用。在這個客戶環境中,首先將_kghdsidx_count調整為3,ORA-04031錯誤即沒有再次出現,調整之後,每個子池的記憶體擴大到750MB左右:
SUBPOOL BYTES MB
------------------------------ ---------- ----------
shared pool (1): 788529152 752
shared pool (2): 788529192 752
shared pool (3): 771751936 736
shared pool (Total): 2348810280 2240
現在每個子池的空閒記憶體達到了20MB~60MB左右:
SUBPOOL NAME SUM(BYTES) MB
------------------------------ -------------------------- ---------- ----------
shared pool (1): free memory 56014080 53.42
shared pool (2): free memory 20292704 19.35
shared pool (3): free memory 67884912 64.74
調整後具體的記憶體使用情況如下,我們注意到,保留池的大塊的空閒記憶體(R-free)數量大大增加,這樣在要請求大塊記憶體時,就更容易獲得共享記憶體資源:
SUBPOOL SGA_HEAP CHUNKCOMMENT size COUNT(*) STATUS BYTES
------- ---------------- ---------------- ----- ---------- -------- ----------
。。。。。。
1 sga heap(1,0) free memory 8-9k 6 free 48016
1 sga heap(1,0) free memory > 10K 4 free 45448
。。。。。。
1 sga heap(1,0) free memory 9-10k 22 R-free 197536
1 sga heap(1,0) free memory > 10K 144 R-free 2606992
。。。。。。
2 sga heap(2,0) free memory 9-10k 8 free 72784
2 sga heap(2,0) free memory > 10K 15 free 172616
......
2 sga heap(2,0) free memory 9-10k 22 R-free 195280
2 sga heap(2,0) free memory > 10K 155 R-free 2839248
。。。。。。
3 sga heap(3,0) free memory 8-9k 14 free 111736
3 sga heap(3,0) free memory 9-10k 1 free 8808
。。。。。。
3 sga heap(3,0) free memory 9-10k 29 R-free 261272
3 sga heap(3,0) free memory > 10K 186 R-free 3434512
客戶的系統是一個雙節點RAC環境,在執行中,應用設定為只連線其中的一個節點,另外一個空閒節點的Shared Pool使用情況如下,列舉供參考:
SUBPOOL SGA_HEAP CHUNKCOMMENT size COUNT(*) STATUS BYTES
------- --------------- ---------------- ----- ---------- -------- ----------
1 sga heap(1,0) free memory 0-1K 373 free 41144
1 sga heap(1,0) free memory 1-2K 1 free 1488
1 sga heap(1,0) free memory 2-3K 1 free 1936
1 sga heap(1,0) free memory 3-4K 1 free 2704
1 sga heap(1,0) free memory 4-5K 1 free 3776
1 sga heap(1,0) free memory 9-10k 4 free 34864
1 sga heap(1,0) free memory > 10K 157 free 460271664
1 sga heap(1,0) free memory > 10K 38 R-free 25520800
2 sga heap(2,0) free memory 0-1K 357 free 37376
2 sga heap(2,0) free memory 3-4K 2 free 6152
2 sga heap(2,0) free memory 4-5K 1 free 3776
2 sga heap(2,0) free memory > 10K 130 free 454592888
2 sga heap(2,0) free memory > 10K 38 R-free 25520800
3 sga heap(3,0) free memory 0-1K 425 free 51280
3 sga heap(3,0) free memory 3-4K 1 free 2704
3 sga heap(3,0) free memory 7-8k 1 free 6664
3 sga heap(3,0) free memory > 10K 44 free 467930312
3 sga heap(3,0) free memory > 10K 38 R-free 25520800
ORA-04031出現時,可能共享池沒有足夠空閒記憶體,但是Shared Pool保留池(shared_pool_reserved_size)還有一定的記憶體空閒,所以我們可以釋放降低使用保留池的記憶體大小,在這個案例中,降低_shared_pool_reserved_min_alloc引數設定,也幫助更好地利用了保留記憶體。
為什麼會在一個 subpool中還有4個 sub partition 如:
sga heap(1,0) sga heap(1,1) sga heap(1,2) sga heap(1,3)
這不是因為 cpu的數目 也不是因為_kghdsidx_count, 而是因為 在10g 中AUTO SGA 引入了 shared pool duration的概念,
duration 分成4類:
- Session duration
- Instance duration (never freed)
- Execution duration (freed fastest)
- Free memory
引入了 shared pool duration的目的是
在10gR1中Shared Pool的shrink收縮操作存在一些缺陷,造成缺陷的原因是在該版本中Buffer Cache還沒有能力共享使用一個granule,這是因為Buffer Cache的granule的尾部由granule header和Metadata(可能是buffer header或者RAC中的Lock Elements)拼接組成,在其尾部不容許存在空洞。另一個原因是當時的shared pool允許不同生命週期duration(以後會介紹)的chunk存放在同一個granule中,這造成共享池無法完全釋放granule。到10gR2中透過對Buffer Cache Granule結構的修改允許在granule header和buffer及Metadata(buffer header或LE)存在縫隙,同時shared pool中不同duration的chunk將不在共享同一個granule,透過以上改進buffer cache與shared pool間的記憶體交換變得可行。此外在10gr2中streams pool也開始支援記憶體交換(實際根據不同的streams pool duration存在限制)
reference :
How To Determine The Default Number Of Subpools Allocated During Startup (文件 ID 455179.1)
In this Document
Goal |
Solution |
The # of CPUs |
The shared pool size |
Manual Memory Mangement |
Automatic Shared Memory Management & Automatic Memory Management |
Number of subpools |
Examples |
Example 1: |
Example 2: |
Example 3: |
Example 4: |
References |
APPLIES TO:
GOAL
This document explains the algorithm for determining the default number of subpools allocated during database startup.
SOLUTION
The calculation for the # of subpools of which the shared pool is comprised at instance startup is based on 3 items:
- the # of CPUs available to Oracle (value A)
- the shared pool size used by the instance (value B)
- whether a hidden instance parameter forces the use of a fixed # of subpools (value C)
The reference to the values A, B, and C will be used in the section "Number of subpools" when determining the actual # of subpools which will be allocated at instance startup.
The # of CPUs
For every 4 CPUs a subpool will be allocated, with a maximum of 7 subpools. The formula used is:
((CPU_COUNT - 1) >> 2) + 1
which leads to:
1 - 4 CPUs = 1 subpool5 - 8 CPUs = 2 subpools9 - 12 CPUs = 3 subpoolsetc.
The shared pool size
The shared pool size is dependent on whether Automatic Shared Memory Management (ASMM)/Automatic Memory Management (AMM) is used or not.
Manual Memory Mangement
In this case, the following instance parameters are not set, or set explicitly to 0:
- SGA_TARGET
- MEMORY_TARGET
When shared memory is managed manually, subpools are configured as follows based on the value of SHARED_POOL_SIZE instance parameter:
Oracle version | Minimum subpool size |
---|---|
9i | 128MB |
10g < 10.2.0.3 | 256MB |
10.2.0.3 and higher | 512MB |
Automatic Shared Memory Management & Automatic Memory Management
Number of subpools
The formula used to calculate the # of subpools at startup is:
if C setthensubpool_count = Celsesubpool_count = min(A, B)
So if the hidden parameter _kghdsidx_count is set (value C), then this is chosen to be the # of pools to be used at instance startup. If the parameter is not set, then the minimum of A and B will be used.
Examples
The following examples describe some cases how to calculate the # of subpools allocated for the shared pool based on given information such as Oracle release, CPU count, and instance memory parameters being set.
Example 1:
The following setup is used:
- Oracle9i is installed
- the system has 12 CPUs
- SHARED_POOL_SIZE is set to 300MB
Example 2:
The following setup is used:
- Oracle11gR2 is installed
- the system has 16 CPUs
- MEMORY_TARGET is set to 4.2GB
- no SGA_TARGET nor SHARED_POOL_SIZE is explicitly set
Example 3:
The following setup is used:
- Oracle11gR2 is installed
- the system has 16 CPUs
- MEMORY_TARGET is set to 96GB
- SGA_TARGET is set to 50GB
Example 4:
The following setup is used:
- Oracle11gR2 is installed
- the system has 16 CPUs
- MEMORY_TARGET is set to 60GB
- SGA_TARGET is set to 30GB
- _kghdsidx_count is set to 4
REFERENCES
About Me
...............................................................................................................................
● 本文整理自網路
● 本文在itpub(http://blog.itpub.net/26736162)、部落格園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文部落格園地址:http://www.cnblogs.com/lhrbest
● 本文pdf版及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 資料庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● QQ群:230161599 微信群:私聊
● 聯絡我請加QQ好友(646634621),註明新增緣由
● 於 2017-04-20 09:00 ~ 2017-05-07 22:00 在魔都完成
● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解
● 版權所有,歡迎分享本文,轉載請保留出處
...............................................................................................................................
拿起手機使用微信客戶端掃描下邊的左邊圖片來關注小麥苗的微信公眾號:xiaomaimiaolhr,掃描右邊的二維碼加入小麥苗的QQ群,學習最實用的資料庫技術。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2138626/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORA-04031:無法分配 32 位元組的共享記憶體記憶體
- Oracle的記憶體分配和使用Oracle記憶體
- C中的記憶體分配模型記憶體模型
- oracle9i 的記憶體分配Oracle記憶體
- Oracle的記憶體的分配、回收[final]Oracle記憶體
- Oracle記憶體分配與調整Oracle記憶體
- Oracle記憶體分配與使用(zt)Oracle記憶體
- Pooled Allocation(池式分配)例項——Keil 記憶體管理記憶體
- Netty 中的記憶體分配淺析Netty記憶體
- Oracle記憶體分配經驗法則Oracle記憶體
- 【SGA】【PGA】普適的Oracle記憶體分配策略Oracle記憶體
- JavaScript記憶體分配JavaScript記憶體
- JVM記憶體分配JVM記憶體
- java記憶體分配Java記憶體
- curl 中減少記憶體分配操作記憶體
- JAVA物件在JVM中記憶體分配Java物件JVM記憶體
- 垃圾收集器與記憶體分配策略_記憶體分配策略記憶體
- 記憶體分配的確定記憶體
- weblogic的記憶體分配Web記憶體
- oracle 記憶體分配和調優 總結Oracle記憶體
- _ksmg_granule_size oracle記憶體分配粒度Oracle記憶體
- 記憶體的分配與釋放,記憶體洩漏記憶體
- JVM 記憶體模型 記憶體分配,JVM鎖JVM記憶體模型
- 共享池記憶體分配和錯誤ORA-00371記憶體
- GO slice 切片-在記憶體中如何分配Go記憶體
- 探索iOS記憶體分配iOS記憶體
- Java 記憶體分配策略Java記憶體
- java jvm 記憶體分配JavaJVM記憶體
- [C++]記憶體分配C++記憶體
- 動態記憶體分配記憶體
- SGA中各池記憶體分配顆粒大小與SGA_TARGET引數的關係記憶體
- 簡單理解動態記憶體分配和靜態記憶體分配的區別記憶體
- 記憶體分配策略中,堆和棧的區別記憶體
- Java中物件並不是都在堆上分配記憶體的。Java物件記憶體
- oracle資料庫記憶體分配(sga和pga)Oracle資料庫記憶體
- C語言的記憶體分配C語言記憶體
- 物件的建立與記憶體分配物件記憶體
- go是如何分配記憶體的?Go記憶體