_shared_pool_reserved_pct or shared_pool_reserved_size with ASMM
共享池是Oracle著名的SGA的一個重要組成部分,當我們嘗試從共享池中分配較大的連續區域時(預設來說是4400bytes),我們可能會用到共享池中的保留區域(也叫保留池);注意Oracle總是會先嚐試掃描普通共享池的空閒列表,之後才嘗試掃描保留池的空閒列表,無論所需分配的記憶體塊是否超過隱式引數_shared_pool_reserved_min_alloc所指定的值。
什麼?你看到過的4031描述文件是用以下虛擬碼描述分配流程的:
large, scan reserved list if (chunk found) check chunk size and perhaps truncate if (chunk is not found) scan regular free list if (chunk found) check chunk size and perhaps truncate all done if (chunk is not found) do LRU operations and repeat small, scan regular free list if (chunk found) check chunk size and perhaps truncate all done if (chunk is not found) do LRU operations and repeat
那麼來看看以下測試:
SQL> alter system set "_shared_pool_reserved_pct"=5 scope=spfile; System altered. SQL> startup frce; SP2-0714: invalid combination of STARTUP options SQL> startup force; ORACLE instance started. Total System Global Area 3154116608 bytes Fixed Size 2099616 bytes Variable Size 2197816928 bytes Database Buffers 939524096 bytes Redo Buffers 14675968 bytes Database mounted. Database opened. SQL> select free_space from v$shared_pool_reserved; FREE_SPACE ---------- 3525368 SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ 2 FROM SYS.x$ksppi x, SYS.x$ksppcv y 3 WHERE x.inst_id = USERENV ('Instance') 4 AND y.inst_id = USERENV ('Instance') 5 AND x.indx = y.indx 6 AND x.ksppinm LIKE '%_shared_pool_reserved_min_alloc%'; NAME VALU DESCRIB ------------------------------- ---- --------------------------------------------------------------------- _shared_pool_reserved_min_alloc 4400 minimum allocation size in bytes for reserved area of shared pool SQL> select count(*) from x$ksmsp where ksmchsiz>4400 and ksmchcom!='free memory'; COUNT(*) ---------- 64 SQL> exec dbms_workload_repository.create_snapshot; PL/SQL procedure successfully completed. SQL> select count(*) from x$ksmsp where ksmchsiz>4400 and ksmchcom!='free memory'; COUNT(*) ---------- 67 /* 方才呼叫的儲存過程成功在共享池中分配到3個大於4400 byte的Chunk,接下來看保留池大小變化) SQL> select free_space from v$shared_pool_reserved; FREE_SPACE ---------- 3525368 /* 保留池大小沒有發生變化,很顯然3個大於4400 byte的Chunk是從regular free list上獲取的,而非reserved free list/
以上實驗中我們透過呼叫awr快照儲存過程,模擬了從共享池中分配大於4400位元組Chunk的操作,實驗結果是在保留池有足夠空閒空間的情況下,Oracle仍嘗試在普通共享池區域中分配了這些連續記憶體,故而透過查詢內部檢視x$ksmsp雖然發現了多出了三個大於4400 byte的Chunk,然而保留池的空閒量並未減少。由此可證即便是要分配大於4400位元組的記憶體塊,Oracle也會先嚐試搜尋普通空閒列表,在普通空閒列表上無適應尺寸的連續空間時,才會嘗試掃描保留池的空閒列表。
言歸正題,我們可以透過2個引數控制保留池的大小:shared_pool_reserved_size和_shared_pool_reserved_pct。這2個引數的區別在於普通引數shared_pool_reserved_size以數值形式制定保留池的大小,這個數值採用在10g的ASMM(自動管理的SGA記憶體管理)特性的環境中是不會隨共享池的大小變化而浮動的;不同於此,隱式引數_shared_pool_reserved_pct作為一個比例值,可以協同ASMM中共享池的變化而適應變化。在討論經典4031錯誤的數個文件中,都有介紹到如果在ASMM環境中,設定_shared_pool_reserved_pct往往要好過shared_pool_reserved_size,它使你的共享池更具可收縮性!
紙上得來終覺淺,我們來看看_shared_pool_reserved_pct的實際效果:
SQL> alter system set sga_max_size=3000M scope=spfile; System altered. SQL> alter system set sga_target=3000M scope=spfile; System altered. SQL> alter system set shared_pool_size=500M; System altered. SQL> alter system set "_shared_pool_reserved_pct"=50 scope=spfile; System altered. SQL> startup force ; ORACLE instance started. Total System Global Area 3154116608 bytes Fixed Size 2099616 bytes Variable Size 570426976 bytes Database Buffers 2566914048 bytes Redo Buffers 14675968 bytes Database mounted. Database opened. SQL> select free_space from v$shared_pool_reserved; FREE_SPACE ---------- 21158280 SQL> alter system set shared_pool_size=2000M ; /*ASMM下手動修改shared_pool_size,模擬共享池自動擴充套件的情況*/ System altered. SQL> select free_space from v$shared_pool_reserved; FREE_SPACE ---------- 21158280 /* ohhh!好像跟我們預期的差別挺大,保留池大小沒變*/ 讓我們跑下這段產生反覆硬解析的SQL: begin for i in 1..200000 loop execute immediate 'select 2 from dual where 1='||i; end loop; end; / SQL> select free_space from v$shared_pool_reserved; FREE_SPACE ---------- 296215920 /* 這樣好了,我們如願了,SGA真"動態" / SQL> alter system set shared_pool_size=300M; /*嘗試收縮ASMM下的共享池*/ System altered. SQL> alter system flush shared_pool; System altered. SQL> select free_space from v$shared_pool_reserved; FREE_SPACE ---------- 296215920 /* 我們甚至無法flush 掉這些記憶體,這挺要命的 / SQL> select name ,value/1024/1024 "SIZE MB" from v$system_parameter where name in ('sga_target','sga_max_size','shared_pool_size','db_cache_size','java_pool_size','large_pool_size','db_keep_cache_size'); NAME SIZE MB -------------------- ---------- sga_max_size 3008 shared_pool_size 304 large_pool_size 16 java_pool_size 16 sga_target 3008 db_cache_size 512 db_keep_cache_size 0 可以看到我們還有很多“沒有分配”的SGA記憶體,我們來加大快取記憶體看看: SQL> alter system set db_cache_size=1000M; alter system set db_cache_size=1000M * ERROR at line 1: ORA-32017: failure in updating SPFILE ORA-00384: Insufficient memory to grow cache /* ohh 因為無法回收保留池的大量記憶體,導致了SGA其他元件無法擴充套件/
_shared_pool_reserved_pct的預設值5%可以滿足絕大多數情況,透過上述實驗證明設定該percent引數可以使保留池大小隨SGA動態調整而擴大;但透過再次調整shared_pool_size和flush shared_pool手段都無法回收過度分配的保留池空間,這會導致其他元件無法正常擴充套件;因而我們在10gASMM的背景下,透過設定_shared_pool_reserved_pct可以獲得更好的效果,但因為存在回收空間的問題,該引數也不宜設定過大,如果預設值在您的場景中顯得過小,那麼您可以嘗試使用5-20這個區間內的值,超過20%的話往往就會造成負面的影響了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-708272/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- asmm , assmASMSSM
- AMM與ASMMASM
- Oracle ASMM和AMMOracleASM
- 關於ASMM和AMMASM
- 一點ASMM總結ASM
- ASMM自動管理的功能ASM
- 有關ASM和ASMM的理解ASM
- SHARED_POOL_RESERVED_SIZE引數的設定及作用
- Oracle 11g AMM與ASMM切換OracleASM
- Oracle的AMM和ASMM以及相關引數探究OracleASM
- ORACLE AMM 、ASMM 、自動記憶體管理(官方手冊)OracleASM記憶體
- ASMM (Auto Shared Memory Manangement) 自動共享記憶體管理ASMNaN記憶體
- 【記憶體管理】Oracle如何使用ASMM自動共享記憶體管理記憶體OracleASM
- 基於引數shared_pool_reserved_size進一步理解共享池shared pool原理
- 自動SGA共享記憶體管理,ASMM,MMAN,sga_target,sga_max_size記憶體ASM
- OracleASM關閉AMM,開啟ASMM,修改引數後報ORA-00843 ORA-00849OracleASM
- 2 Day DBA-管理方案物件-監控和優化資料庫-獲取ASMM記憶體尺寸建議物件優化資料庫ASM記憶體
- ASMM/AMM開啟時動態調整記憶體元件(shared_pool_size, db_cache_size等)大小ASM記憶體元件