概念對比介紹
相信有些人會對ORACLE當中的AMM(Automatic Memory Management)與ASMM(Automatic Shared Memory Management)有些迷惑或混淆,不清楚兩者的異同,本文會從幾個方面來總結一下兩者的異同。如有不足或疏漏之處,敬請指正!
從ORACLE發布的版本歷史(時間軸)來看,ORACLE的內存管理的大致歷程如下:
ORACLE 9i PGA自動管理,SGA手動管理
ORACLE 10g PGA自動管理,SGA自動管理(ASMM,自動共享內存管理)
ORACLE 11g PGA,SGA統一自動管理(AMM,自動內存管理)
ORACLE 12c 跟11g一樣,沒有變化
官方文檔的介紹資料如下:
· Oracle 9i
· Beginning with Oracle9i, the dynamic SGA infrastructure allowed for the sizing of the Buffer Cache, Shared Pool and the Large Pool without having to shut down the database. Key features being:
o Dynamic Memory resizing
o DB_CACHE_SIZE instead of DB_BLOCK_BUFFERS
o DB_nK_CACHE_SIZE for multiple block sizes
o PGA_AGGREGATE_TARGET Introduction of Automatic PGA Memory management
· Oracle Database 10g
· Automatic Shared Memory Management (ASMM) was introduced in 10g. You enable the automatic shared memory management feature by setting the SGA_TARGET parameter to a non-zero value.
· Oracle Database 11g
· Automatic Memory Management is being introduced in 11g. This enables automatic tuning of PGA and SGA with use of two new parameters named MEMORY_MAX_TARGET and MEMORY_TARGET
· Oracle Database 12c
Automatic Memory Management keeps the same behaviour as in 11g.
自動共享內存管理(Automatic Shared Memory Management ASMM)是ORACLE 10g開始引入的的新技術,ASMM用來實現SGA的自動管理。。當啟用自動共享內存管理后,不再需要為每個內存組件設定值,當然如果你設置SGA_TARGET的同時,設置了db_cache_size、shared_pool_size這些參數,那么db_cache_size、shared_pool_size這些參數值會作為最小值要求。官方關於Automatic Shared Memory Management的介紹如下:
Automatic Shared Memory Management
In previous database releases, a database administrator (DBA) was required to manually specify different SGA component sizes by setting a number of initialization parameters, including the SHARED_POOL_SIZE, DB_CACHE_SIZE, JAVA_POOL_SIZE, and LARGE_POOL_SIZE parameters. Oracle Database 10g includes the Automatic Shared Memory Management feature which simplifies the SGA memory management significantly. In Oracle Database 10g, a DBA can simply specify the total amount of SGA memory available to an instance using the SGA_TARGET initialization parameter and the Oracle Database will automatically distribute this memory among various subcomponents to ensure most effective memory utilization.
When automatic SGA memory management is enabled, the sizes of the different SGA components are flexible and can adapt to the needs of a workload without requiring any additional configuration. The database automatically distributes the available memory among the various components as required, allowing the system to maximize the use of all available SGA memory.
ORACLE 10G版本開始推出了ASMM,自動SGA管理,它的出現一定程度上幫助DBA解決了管理SGA的問題,通過設置參數SGA_TARGET來控制ASMM,其中SGA_TARGET為零表示禁用ASMM,非零值表示啟用ASMM。但是在10G R1等早期版本,ASMM還不夠成熟,而且存在比較多的BUG,導致了比較多的問題。在ORACLE 10g R2后續版本中,ASMM才逐漸完善並成熟。
到了11g之后,ORACLE又實現了PGA和SGA的統一自動管理 ,這個稱之為自動化內存管理(Automatic Memory Management,AMM)。從這些演化歷程來看,ORACLE從最開始的手動配置各個組件參數,慢慢逐漸向智能化、傻瓜化、自動化的方向穩步前進。這個是一個必然的歷史趨勢。關於AMM的官方文檔介紹如下:
About Automatic Memory Management
The simplest way to manage instance memory is to allow the Oracle Database instance to automatically manage and tune it for you. To do so (on most platforms), you set only a target memory size initialization parameter (MEMORY_TARGET) and optionally a maximum memory size initialization parameter (MEMORY_MAX_TARGET). The instance then tunes to the target memory size, redistributing memory as needed between the system global area (SGA) and the instance program global area (instance PGA). Because the target memory initialization parameter is dynamic, you can change the target memory size at any time without restarting the database. The maximum memory size serves as an upper limit so that you cannot accidentally set the target memory size too high, and so that enough memory is set aside for the Oracle Database instance in case you do want to increase total instance memory in the future. Because certain SGA components either cannot easily shrink or must remain at a minimum size, the instance also prevents you from setting the target memory size too low.
If you create your database with Database Configuration Assistant (DBCA) and choose the basic installation option, automatic memory management is enabled. If you choose advanced installation, Database Configuration Assistant (DBCA) enables you to select automatic memory management.
ORACLE 11g AMM 的引入, 組合出來有 5 種內存管理形式.
自動內存管理(AMM) : memory_target=非0,是自動內存管理,如果初始化參數 LOCK_SGA=TRUE,則 AMM 是不可用的。
自動共享內存管理(ASMM): 在memory_target=0 and sga_target為非0的情形下是自動內存管理
手工共享內存管理 : memory_target=0 and sga_target=0 指定 share_pool_size 、db_cache_size 等 sga 參數
自動 PGA 管理 : memory_target=0 and workarea_size_policy=auto and PGA_AGGREGATE_TARGET=值
手動 PGA 管理 : memory_target=0 and workarea_size_policy=manal 然后指定 SORT_AREA_SIZE 等 PGA 參數,一般不使用手動管理PGA。
Oracle Database 11g supports various memory management methods, which are chosen by initialization parameter settings. Oracle recommends that you enable the automatic memory management method.
- Automatic Memory Management – For Both the SGA and Instance PGA
- Automatic Shared Memory Management – For the SGA
- Manual Shared Memory Management – For the SGA
- Automatic PGA Memory Management –For the Instance PGA
- Manual PGA Memory Management – For the Instance PGA
ASMM切換到AMM
如下所示,當前實驗環境下自動內存管理已被禁用(memory_target=0)
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> show parameter memory_target ;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
memory_target big integer 0
SQL> show parameter memory_max_target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
memory_max_target big integer 0
SQL>
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 1G
sga_target big integer 1G
在11g中,如果使用ASMM,對應的內存共享段是真實的共享段。
SQL> !
[oracle@DB-Server ~]$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 4128770 root 644 80 2
0x00000000 4161540 root 644 16384 2
0x00000000 4194309 root 644 280 2
0xfc5d1940 7012369 oracle 660 1075838976 49
如下所示,首先檢查參數文件類型,然后修改參數sga_target、memory_max_target、memory_target。因為當中有些參數為靜態參數,所以在修改參數后,需要重啟數據庫。
SQL> show parameter spfile;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
spfile string /u01/app/oracle/product/11.1.0
/dbhome_1/dbs/spfilegsp.ora
SQL> alter system set sga_max_size=0 scope=spfile;
System altered.
SQL> alter system set sga_target=0 scope=spfile;
System altered.
SQL> alter system set pga_aggregate_target=0 scope=spfile;
SQL> alter system set memory_max_target=1G scope=spfile;
System altered.
SQL> alter system set memory_target=1G scope=spfile;
System altered.
SQL>
重啟數據庫后,檢查對應參數。
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 517816320 bytes
Fixed Size 2214776 bytes
Variable Size 159384712 bytes
Database Buffers 348127232 bytes
Redo Buffers 8089600 bytes
Database mounted.
SQL> show parameter memory
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
hi_shared_memory_address integer 0
memory_max_target big integer 1G
memory_target big integer 1G
shared_memory_address integer 0
SQL>
自動內存管理(AMM)啟動之后,系統共享段變為“虛擬”共享段。
[oracle@DB-Server ~]$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 4128770 root 644 80 2
0x00000000 4161540 root 644 16384 2
0x00000000 4194309 root 644 280 2
0xfc5d1940 7077905 oracle 660 4096 0
11g MEMORY_TARGET Parameter Dependency
那么有個疑問,自動內存管理(AMM)模式下面,sga_max_size、sga_target、memory_max_target、memory_target、pga_aggregate_target這幾個參數的關系是什么樣的呢?其實官方文檔已經有詳細闡述
If MEMORY_TARGET is set to a non-zero value:
· If SGA_TARGET and PGA_AGGREGATE_TARGET are set, they will be considered the minimum values for the sizes of SGA and the PGA respectively. MEMORY_TARGET values can range from SGA_TARGET + PGA_AGGREGATE_TARGET to MEMORY_MAX_TARGET.
· If SGA_TARGET is set and PGA_AGGREGATE_TARGET is not set, we will still auto-tune both parameters. PGA_AGGREGATE_TARGET will be initialized to a value of MEMORY_TARGET - SGA_TARGET.
· If PGA_AGGREGATE_TARGET is set and SGA_TARGET is not set, we will still auto-tune both parameters. SGA_TARGET will be initialized to the minimum non-zero value of MEMORY_TARGET - PGA_AGGREGATE_TARGET and SGA_MAX_SIZE and will auto tune its components.
· If neither is set, they will be auto-tuned without any minimum or default values. We will have a policy of distributing the total memory set by MEMORY_TARGET parameter in a fixed ratio to the the SGA and PGA during initialization. The policy is to give 60% to the SGA and 40% to the PGA at startup.
If MEMORY_MAX_TARGET has not been explicitly set, but MEMORY_TARGET has, the instance automatically sets MEMORY_MAX_TARGET to the same value as MEMORY_TARGET. If MEMORY_TARGET has not been explicitly set, but MEMORY_MAX_TARGET has, then MEMORY_TARGET defaults to 0. After instance startup, it then is possible to dynamically change MEMORY_TARGET to a non-zero value, provided that it does not exceed the value of MEMORY_MAX_TARGET.
If MEMORY_TARGET is not set or set to set to 0 explicitly (default value is 0 for 11g):
· If SGA_TARGET is set we will only auto-tune the sizes of the components of the SGA. PGA will be autotuned independent of whether it is explicitly set or not. However, the combination of SGA and PGA will not be auto-tuned, i.e. the SGA and PGA will not share memory and resize as with the case of MEMORY_TARGET being set to a non-zero value.
· If neither SGA_TARGET nor PGA_AGGREGATE_TARGET is set, we will follow the same policy as we have today; PGA will be auto-tuned and the SGA will not be auto-tuned and parameters for some of the SGA components will have to be set explicitly (for SGA_TARGET).
· If only MEMORY_MAX_TARGET is set, MEMORY_TARGET will default to 0 and we will not auto tune the SGA and PGA. It will default to 10gR2 behavior.
· If SGA_MAX_SIZE is not user set, it is internally set to MEMORY_MAX_TARGET.
我們下面還是通過實驗一一驗證一下:
1:當MEMORY_TARGET大於0的情況下,可以設置SGA_TARGET、PGA_AGGREGATE_TARGET的值為非0,對應的意義分別如下:
如果設置了SGA_TARGET和PGA_AGGREGATE_TARGET,它們分別表示SGA的的最小值和PGA的最小值。MEMORY_TARGET值的范圍可以從SGA_TARGET + PGA_AGGREGATE_TARGET到MEMORY_MAX_TARGET。
當然SGA_TARGET + PGA_AGGREGATE_TARGET的和必須小於等於memory_target,另外,如果同時設置了sga_target、pga_aggregate_target的值,memory_target的值必須大於等於sga_target與pga_aggregate_target之和。如下測試所示:
SQL> alter system set pga_aggregate_target=200m scope=both;
System altered.
SQL> show parameter pga_aggregate_target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target big integer 200M
SQL>
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 496M #后面講述為什么sga_max_size為什么沒有被置為0
sga_target big integer 0
SQL> alter system set sga_target=400m scope=both;
System altered.
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 496M
sga_target big integer 400M
SQL>
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 496M
sga_target big integer 400M
SQL> show parameter pga_aggregate_target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target big integer 200M
SQL> alter system set memory_target=696m scope=both;
System altered.
SQL> alter system set memory_target=600m scope=both;
System altered.
SQL> alter system set memroy_target=500m scope=both;
alter system set memroy_target=500m scope=both
*
ERROR at line 1:
ORA-02065: illegal option for ALTER SYSTEM
SQL> alter system set memory_target=500m scope=both;
alter system set memory_target=500m scope=both
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 600M
SQL> show parameter memory_target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
memory_target big integer 600M
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 496M
sga_target big integer 400M
SQL> show parameter pga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target big integer 200M
SQL>
SQL>
SQL> alter system set pga_aggregate_target=201m scope=both;
alter system set pga_aggregate_target=300m scope=both
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00840: PGA_AGGREGATE_TARGET cannot be modified to the specified value
如上測試所示,如果設置了pga_aggregate_target和sga_target,那么pga_aggregate_target + sga_target 必須小於等於memory_target,另外,memory_target也必須大於等於(pga_aggregate_target + sga_target)
如果設置了SGA_TARGET並且PGA_AGGREGATE_TARGET沒有設置,數據庫仍然會自動調整這兩個參數。 PGA_AGGREGATE_TARGET將被初始化為MEMORY_TARGET - SGA_TARGET的值。
如果設置了PGA_AGGREGATE_TARGET並且沒有設置SGA_TARGET,數據庫仍然會自動調整這兩個參數。 SGA_TARGET將被初始化為MEMORY_TARGET - PGA_AGGREGATE_TARGET,並在這個值和SGA_MAX_SIZE這個區間范圍內自動調整
如果SGA_TARGET和PGA_AGGREGATE_TARGET兩者都沒有設置的話,則它們將被自動調諧而沒有任何最小值或默認值。 我們將有一個策略,在初始化過程中,將由MEMORY_TARGET參數設置的總內存以固定的比例分配給SGA和PGA。 政策是在啟動時給予SGA 60%和PGA 40%給PGA。
2: 沒有設置SGA_MAX_SIZE,但是為什么SGA_MAX_SIZE一直有值,即使將其設置為0或使用reset alter system set sga_max_size=0 scope=spfile; SGA_MAX_SIZE一直有值。官方關於SGA_MAX_SIZE的介紹如下:
SGA_MAX_SIZE specifies the maximum size of the SGA for the lifetime of the instance.
On 64-bit platforms and non-Windows 32-bit platforms, when either MEMORY_TARGET or MEMORY_MAX_TARGET is specified, the default value of SGA_MAX_SIZE is set to the larger of the two parameters. This causes more address space to be reserved for expansion of the SGA.
On Windows 32-bit platforms, the default value of SGA_MAX_SIZE is the largest of the following values:
·
· 60% of MEMORY_TARGET, if specified
·
· 60% of MEMORY_MAX_TARGET, if specified
·
· 25% of the total available virtual address space
也就是說在64位平台和非Windows 32位平台上,當指定MEMORY_TARGET或MEMORY_MAX_TARGET時,SGA_MAX_SIZE的默認值將設置為兩個參數中較大的一個。 這導致更多的地址空間被保留用於SGA的擴展。 這也是之前一直讓我迷惑的地方。另外,官方文檔建議:當切換到AMM,即使用MEMORY_TARGET時,不應該設置參數SGA_MAX_SIZE(用於ASMM),因為這樣做會修復SGA的大 小,因此與MEMORY_TARGET的預期用法相沖突。(原文:Check also for SGA_MAX_SIZE being set. When switching to AMM, i.e. using MEMORY_TARGET, the parameter SGA_MAX_SIZE (used for ASMM) should not be set as doing so fixes the size of the SGA, and hence conflicts with the intended use of MEMORY_TARGET.)
|
SGA_MAX_SIZE的值最好不要去修改,如果其值大於MEMORY_MAX_TARGET的話,就報ORA-00844 & ORA-00851 錯誤。如下所示
SQL> alter system set sga_max_size=1025M scope=spfile;
System altered.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00844: Parameter not taking MEMORY_TARGET into account
ORA-00851: SGA_MAX_SIZE 1090519040 cannot be set to more than MEMORY_TARGET 637534208.
SQL>
此時需要生成對應spfile的pfile文件,然后找到*.sga_max_size這個值,刪除后重新生成對應的spfile,啟動數據庫實例即可,當然你也可以設置其值大於MEMORY_TARGET即可。
AMM切換到ASMM
SQL> show parameter target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
archive_lag_target integer 0
db_flashback_retention_target integer 1440
fast_start_io_target integer 0
fast_start_mttr_target integer 0
memory_max_target big integer 1552M
memory_target big integer 1552M
parallel_servers_target integer 16
pga_aggregate_target big integer 0
sga_target big integer 0
SQL> alter system set memory_max_target=0 scope=spfile;
System altered.
SQL> alter system set memory_target=0 scope=spfile;
System altered.
SQL> alter system set pga_aggregate_target=200m scope=spfile;
System altered.
SQL> alter system set sga_max_size=1g scope=spfile;
System altered.
SQL> alter system set sga_target=1g scope=spfile;
System altered.
SQL>
SQL> startup
ORA-00843: Parameter not taking MEMORY_MAX_TARGET into account
ORA-00849: SGA_TARGET 1073741824 cannot be set to more than MEMORY_MAX_TARGET 0.
SQL>
生成對應的spfile的pfile文件,然后刪除memory_max_target和memory_target兩個參數后,然后生成對應的spfile,最后重啟數據庫實例即可。
SQL> create pfile from spfile;
File created.
*.memory_max_target=0
*.memory_target=0
SQL> create spfile from pfile;
File created.
SQL>
選擇AMM還是HugePages
ORACLE 11g開始推出AMM,它是ORACLE在ASMM的基礎上的進一步內存管理自動化的演進。ASMM是自動管理SGA,而AMM則是將SGA與PGA聯合起來自動管理、調整。只需要設置memory_target一個參數就可以完成整個數據庫實例內存的配置。但是這個功能沒被廣泛使用,因為AMM最大的問題在於不能使用標准大頁。有時候為了使用標准大頁功能,可能有些系統會禁用AMM.那么到底是用AMM還是使用大頁呢?很多人(大師)傾向使用大頁功能而非AMM,關於這個可以參考下面博文
MEMORY_TARGET (SGA_TARGET) or HugePages – which to choose?
Oracle Memory Management and HugePage
如何從AMM切換到HugePage,可以參考官方文檔(ID 2128928.1)
How To Convert A Database Using AMM (Automatic Memory Management) To A Database That Has Been Configured With Hugepage
參考資料:
https://docs.oracle.com/cd/E18283_01/server.112/e17110/initparams230.htm
http://www.dba-oracle.com/t_amm_automatic_memory.htm
https://docs.oracle.com/cd/B28359_01/server.111/b28310/memory003.htm#ADMIN11011
https://www.jianshu.com/p/9715280a4ced
http://oracle-help.com/oracle-database/relationship-memory_target-sga_target-pga_aggregate_target/
https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=275836827924018&id=443746.1&_afrWindowMode=0&_adf.ctrl-state=149nyur949_198