SGA_MAX_SIZE與SGA_TARGET
原文地址:http://chenzs19850728.blog.163.com/blog/static/7629609200822374034376/
Oracle的SGA包括以下幾個部分,可以透過show sga命令或者是透過檢視v$sga檢視來檢視SGA的大概組成:
17:39:48 SQL> show sga
Total System Global Area 1048576000 bytes
Fixed Size 1223392 bytes
Variable Size 847250720 bytes
Database Buffers 192937984 bytes
Redo Buffers 7163904 bytes
17:42:05 SQL> select * from v$sga;
NAME VALUE
------------------------------ -------------
Fixed Size 1223392.00
Variable Size 847250720.00
Database Buffers 192937984.00
Redo Buffers 7163904.00
從上面可以大致的看到sga包括一個固定區,一個可變區,一個資料庫快取和一個redo快取。這些是比較籠統的資訊,具體的SGA是由以下幾個部分組成的:
- 資料緩衝(Buffer Cache)
- 共享池(Shared Pool)
- 大池(Large Pool)
- Java池(Java Pool)
- 流池(Streams Pool --- 10g以後才有)
- 重做日誌緩衝(Redo Log Buffer)
- 其他buffer caches(如KEEP, RECYCLE, and other block sizes cache等)
- Fixed SGA and other internal allocations。
其中,Shared Pool、Java Pool、Large Pool和Streams Pool這幾塊記憶體區的大小是相應系統引數設定而改變的,所以有通稱為可變SGA(Variable SGA)。最後一個fixed sga部分,一般是在例項啟動以後就固定在sga中了,是不會發生變化的,這個部分的區域一般小於100k。
理解了SGA的組成以後,下面就來解釋一下有關設定SGA大小的兩個引數SGA_MAX_SIZE和SGA_TARGET的含義。
SGA_MAX_SIZE
這個引數顧名思義,它用來控制SGA使用虛擬記憶體的最大大小,這裡的虛擬記憶體的含義可能會有所模糊,先可以這樣理解,就是Oracle所能在記憶體中給SGA分配的最大大小。
現在來解釋一下我這裡“虛擬記憶體”的含義,確切的應該這樣說:實際記憶體和虛擬記憶體。我們知道當OS中實際記憶體不夠使用的時候,OS就會去使用虛擬記憶體。oracle是執行與os之上的一個系統軟體,它也是一個程式,它所請求os給它多少記憶體用來作為其sga(比方說Oracle申請500M記憶體用作SGA,即SGA_MAX_SIZE=500M),os一般是不會在oracle啟動的時候就給它全部的實際記憶體,而可能只給200M。隨著程式的執行,Oracle不斷的需要記憶體,而假設計算機的所有實際記憶體只有500M,那麼很肯定的是OS不可能把全部500M實際記憶體分配給oracle的sga,可能也最多就給了350M,剩下的150M使用虛擬記憶體。Oracle的SGA達到500M的時候(即達到SGA_MAX_SIZE指定的大小),實際上這個sga由350M實際記憶體和150M的虛擬記憶體組成,如果這個時候Oracle想繼續申請記憶體給SGA使用,那麼OS是不會再給其分配記憶體,因為它已經達到了SGA_MAX_SIZE的最大值。這個例子,雖然比較極端,即使OS實際上比方說有1G記憶體,Oracle的SGA也未必全部由實際記憶體組成,可能是由400M實際記憶體和100M的虛擬記憶體組成,這是由作業系統的記憶體管理策略決定的。此時,很顯然有個問題,假設我的機器實體記憶體(實際記憶體)足夠多,如何讓Oracle所申請的SGA記憶體全部在實體記憶體中呢,因為假設使用了虛擬記憶體,必定會帶來額外的PAGE IN/PAGE OUT的I/O操作,這是很不合算的。這個問題其實就是在實體記憶體中固定SGA的問題,這要涉及到另外兩個引數LOCK_SGA和PRE_PAGE_SGA以及具體作業系統是否支援記憶體鎖定的問題了,對此在這不予討論。因此可以簡潔的這樣說:當例項啟動後,各個記憶體區只分配例項所需要的最小大小,在隨後的執行過程中,再根據需要擴充套件他們的大小,而他們的總和大小受到了SGA_MAX_SIZE的限制。
根據前面的SGA的組成介紹,我們很容易得到一個計算SGA的實際值的公式,如下:
SGA實際大小 = DB_CACHE_SIZE
+ DB_KEEP_CACHE_SIZE
+ DB_RECYCLE_CACHE_SIZE
+ DB_nk_CACHE_SIZE
+ SHARED_POOL_SIZE
+ LARGE_POOL_SIZE
+ JAVA_POOL_SIZE
+ STREAMS_POOL_SIZE(10g中的新記憶體池)
+ LOG_BUFFERS+11K(Redo Log Buffer的保護頁)
+ 1MB
+ 16M(SGA內部記憶體消耗,適合於9i及之前版本)
而SGA_MAX_SIZE就是它的各個部分記憶體區都達到定義的最大值的時候的大小之和。
修改SGA_MAX_SIZE的大小,必須要重新啟動資料庫例項。
這樣就可能出現這樣的一種情況,在spfile中,SGA各個記憶體區設定大小總和大於SGA_MAX_SIZE。這時,oracle會如下處理:當例項再次啟動時,如果發現SGA各個記憶體總和大於SGA_MAX_SIZE,它會將SGA_MAX_SIZE的值修改為SGA各個記憶體區總和的值。
SGA_TARGET
在Oracle 10g中引入了一個非常重要的引數:SGA_TARGET,這也是Oracle 10g的一個新特性。
在10g之前,SGA的各個記憶體區的大小都需要透過各自的引數指定,並且都無法超過引數指定大小的值,儘管他們之和可能並沒有達到SGA的最大限制。此外,一旦分配後,各個區的記憶體只能給本區使用,相互之間是不能共享的。拿SGA中兩個最重要的記憶體區Buffer Cache和Shared Pool來說,它們兩個對例項的效能影響最大,但是就有這樣的矛盾存在:在記憶體資源有限的情況下,某些時候資料被cache的需求非常大,為了提高buffer hit,就需要增加Buffer Cache,但由於SGA有限,只能從其他區“搶”過來——如縮小Shared Pool,增加Buffer Cache;而有時又有大塊的PLSQL程式碼被解析駐入記憶體中,導致Shared Pool不足,甚至出現4031錯誤,又需要擴大Shared Pool,這時可能又需要人為干預,從Buffer Cache中將記憶體奪回來。
有了這個新的特性後,SGA中的這種記憶體矛盾就迎刃而解了。這一特性被稱為自動共享記憶體管理(Automatic Shared Memory Management ASMM),控制這一特性的,就僅僅是這個引數SGA_TARGE。設定這個引數後,你就不需要為每個記憶體區來指定大小了。SGA_TARGET指定了SGA可以使用的最大記憶體大小,而SGA中各個記憶體的大小由Oracle自行控制,不需要人為指定。Oracle可以隨時調節各個區域的大小,使之達到系統效能最佳狀態的個最合理大小,並且控制他們之和在SGA_TARGET指定的值之內。一旦給SGA_TARGET指定值後(預設為0,即沒有啟動ASMM),就自動啟動了ASMM特性。
當啟用Oracle的ASMM新特性以後,也不是SGA的所有區的大小都開始動態起來,只有以下的這些區的記憶體大小動態共享起來:
* Buffer cache (DB_CACHE_SIZE)
* Shared pool (SHARED_POOL_SIZE)
* Large pool (LARGE_POOL_SIZE)
* Java pool (JAVA_POOL_SIZE)
* Streams pool (STREAMS_POOL_SIZE)
而SGA中的其他區域的記憶體大小仍然是固定不共享的。
SGA_TARGET引數帶來了ASMM的新特性,但是它的含義和SGA_MAX_SIZE的一樣,也表示SGA最大的大小,於是它也就有了一個限制,那就是它的大小不能大於SGA_MAX_SIZE的大小。請看:
18:29:32 SQL> show parameter sga
NAME TYPE VALUE
------------------------------------ --------------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 1000M
sga_target big integer 300M
18:29:36 SQL> alter system set sga_target=1100m;
alter system set sga_target=1100m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00823: Specified value of sga_target greater than sga_max_size
從上面這個例子的錯誤報告中,我們還可以發現一點那就是SGA_TARGET是可以在本例項內動態修改的,請看:
18:29:46 SQL> alter system set sga_target=500m;
System altered.
問題又出現了,既然SGA_TARGET除了帶來這個ASMM新特性以及可動態修改以外,它的含義和SGA_MAX_SIZE是一樣的,即表示Oracle所能使用的SGA的最大大小。那麼這裡就有兩個最大,雖然有限制SGA_TARGET不能大於SGA_MAX_SIZE大小,可是並沒有限制它比它小啊。因此,當SGA_TARGET小於SGA_MAX_SIZE的時候,這兩個最大,Oracle該聽誰的呢?前面的例子,我們知道SGA_TARGET=500M < SGA_MAX_SIZE=1000M,那麼繼續試驗,請看:
18:31:04 SQL> startup force
ORACLE instance started.
Total System Global Area 1048576000 bytes
Fixed Size 1223392 bytes
Variable Size 637535520 bytes
Database Buffers 402653184 bytes
Redo Buffers 7163904 bytes
Database mounted.
Database opened.
18:35:17 SQL> show parameter sga
NAME TYPE VALUE
------------------------------------ --------------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 1000M
sga_target big integer 500M
18:35:31 SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
從這個版本來看,這裡似乎並沒有發生改變。那說明是什麼問題呢?很顯然,SGA_MAX_SIZE仍然表示SGA的大小的上限值,而SGA_TARGET是SGA的所有元件的大小的最大值之和,即當SGA_TARGET< SGA_MAX_SIZE的時候,oracle就會忽略SGA_MAX_SIZE的值,SGA_TARGET也就成了SGA的在此例項中的上限制,它能動態改變大小,但是不能夠大於SGA_MAX_SIZE的值。
有人曾經做過試驗,在某些版本中(可能在我的版本之後的版本),當SGA_TARGET < SGA_MAX_SIZE時,例項重啟以後SGA_MAX_SIZE就變成SGA_TARGET的大小了。
那麼這就說明SGA_TARGET的處理,在不同的版本中是不一樣的。那麼在最新的11g中是什麼樣子的呢?下面來看看,也讓我們猜測一下oracle對SGA_TARGET的處理方向:
18:52:15 SQL> show parameter sga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 276M
sga_target big integer 0
18:52:31 SQL> alter system set sga_target=200m;
System altered.
18:52:38 SQL> show parameter sga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 276M
sga_target big integer 276M
18:52:43 SQL> alter system set sga_target=202M;
alter system set sga_target=202M
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00827: could not shrink sga_target to specified value
18:53:11 SQL> alter system set sga_target=322M;
alter system set sga_target=322M
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00823: Specified value of sga_target greater than sga_max_size
18:57:50 SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for Linux: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
從試驗中很顯然的看到,在11g中,這個SGA_TARGET只能設定是等於SGA_MAX_SIZE的大小了,設定比它小,oracle會自動幫你調整,設定比它大,那還是出錯。現在可以自己想想,oracle對SGA_TARGET的大小處理在往正確的簡單的方向前進中。
SGA_TARGET帶來一個重要的好處就是,能使SGA的利用率達到最佳,從而節省記憶體成本。因為ASMM啟動後,Oracle會自動根據需要調整各個區域的大小,大大減少了某些區域記憶體緊張,而某些區域又有記憶體空閒的矛盾情況出現。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30496894/viewspace-1845633/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- sga_target與sga_max_size
- 【轉】SGA_MAX_SIZE與SGA_TARGET
- 轉:關於SGA_MAX_SIZE與SGA_TARGET的詳解
- oracle 10g中的SGA_MAX_SIZE與SGA_TARGET引數Oracle 10g
- 關於memory_max_target,memory_target,sga_max_size,sga_target
- 自動SGA共享記憶體管理,ASMM,MMAN,sga_target,sga_max_size記憶體ASM
- sga_target與max_sga_size
- statistics_level與SGA_TARGET衝突
- The SGA_MAX_SIZE Initialization Parameter (72)
- SGA_TARGET Advice
- sga_target大小調整
- The SGA_TARGET Initialization Parameter (74)
- oracle 重設定sga_targetOracle
- Dynamic Modification of SGA_TARGET (103)
- Oracle10g修改SGA_TARGETOracle
- 改sga_target的注意事項
- Oracle Rac 修改SGA_TARGET值無變化Oracle
- 10g中的sga_target引數
- SGA中各池記憶體分配顆粒大小與SGA_TARGET引數的關係記憶體
- memory_target、sga_target、pga_target的設定
- 修改sga_target引起的ora-27100 bug嗎
- 11g下設定sga_max_size=4g時出現的報錯
- memory_max_target,memory_target,pga_aggregate_target,sga_target
- ORA-00824:cannot set sga_target due to existing internal setting --SOLUTION
- 9i 下sga_max_size 和SGA中各記憶體分配項的關係記憶體
- 【例項】之memory_target、sga_target,pga_aggregate_target關係
- Linux核心引數(如kernel.shmmax)及Oracle相關引數調整(如SGA_MAX_SIZE)LinuxHMMOracle
- [20190507]sga_target=0注意修改_kghdsidx_count設定.txt
- ORA-00843,ORA-00849 When Trying To Change SGA_TARGET With MEMORY_MAX_TARGET=0
- DB startup fail with ORA-00064 Errors with huge sga_target over 40Gig_886312.1AIError
- [20190104]sga_target 的設定和ORA-04031錯誤.txt
- 10g中同時設定了SGA_TARGET和SHARED_POOL_SIZE的問題
- 19c ADG環境中主庫PDB調整SGA_TARGET自動同步到備庫
- sga_target設定大於100G遇到的一個bug ORA-00064: object is too largeObject
- 手工建庫啟動例項時一個小錯誤:ORA-00824: cannot set sga_target due to existing internal settings
- undefined與null與?. ??UndefinedNull
- &與&&, |與||區別
- 進與穩,時代與技術,新基建與華為雲