ORACLE11G自动内存管理Automatic Memory Management(AMM)
ORACLE近期的版本都对内存管理做了简化,从9i通过PGA_AGGREGATE_TARGET参数实现PGA的自动管理,10g通过Automatic Shared Memory Management(ASMM)实现SGA的自动管理,到11g通过Automatic Memory Management(AMM)实现内存(SGA+PGA)的自动管理。目前的11G版本,DBA只需要设置2个或者一个参数,就可以实现ORACLE对内存的自动管理。
由于11G(AMM)的引入,DBA只需要设置一个或两个参数就可以实现ORACLE对整个内存块的自动管理。memory_max_target参数指定了ORACLE可以分配的最大内存大小,如果不指定memory_target参数,默认为0,即和memory_max_target同样大小。
[oracle@dbserver1 ~]$ sqlplus / as sysdba Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 3088M memory_target big integer 3088M shared_memory_address integer 0
此时sga_target和pga_aggregate_target为ORACLE自动管理,大小都为0。
SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 2600M sga_target big integer 0 SQL> show parameter pga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ pga_aggregate_target big integer 0
DBA也可以手动设置sga_max_size的大小来限制SGA的大小,但是需要注意的是,SGA的大小并不是DBA随心所欲限制的,在有些情况下,SGA的大小是受memory_max_target的大小限制的,比如以下实验:
注:由于本人较懒,而且实验时比较匆忙,也是在测试环境下错的实验,下面实验用到的startup force命令是很危险的操作,不建议在正式环境下使用,做完实验之后,这个命令本人已经忘啦,希望看到这个命令的人也可以当作没看到或者看后忘掉。我的实验做的比较浅,有兴趣的人可以在测试的时候看下v$memory_dynamic_components和其他一些内存有关的视图,看下每个过程具体内存是怎么分配的。
SQL> alter system set sga_max_size=500M scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 1920847872 bytes Fixed Size 2241320 bytes Variable Size 654314712 bytes Database Buffers 1254096896 bytes Redo Buffers 10194944 bytes Database mounted. Database opened. SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 1840M sga_target big integer 0 SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 3088M memory_target big integer 3088M shared_memory_address integer 0
虽然我设置sga_max_size的大小为500M,但实际上ORACLE将sga_max_size的大小设置为1840M,我做了很多次试验,大多情况下,将memory_max_target和sga_max_size的大小从大往小调整,sga_max_size的实际大小都受memory_max_target的大小制约,但是从小往大调整,很少见到sga_max_size的实际大小都受memory_max_target的大小制约的情况。以下实验之前已将memory_max_target设置为1G,sga_max_size大小设置为500M,需要注意的是本环境64位的ORACLE,sga_max_size的大小最小为500M,如果小于500M会出现ORA-04031错误。
ORA-04031: unable to allocate 32 bytes of shared memory ("shared pool","SELECT DECODE(null,'','Total...","SQLA","tmp")
以下实验为验证将memory_max_target和sga_max_size的值从小往大改,sga_max_size的大小是否受memory_max_target大小的限制。
SQL> alter system set memory_max_target=2g scope=spfile; System altered. SQL> alter system set memory_target=2g scope=spfile; System altered. SQL> alter system set sga_max_size=600M scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 626327552 bytes Fixed Size 2229080 bytes Variable Size 310381736 bytes Database Buffers 306184192 bytes Redo Buffers 7532544 bytes Database mounted. Database opened. SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 2G memory_target big integer 2G shared_memory_address integer 0 SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 600M sga_target big integer 0
此时将memory_max_target设置为2G,sga_max_size设置为500M,sga_max_size参数的大小没有受memory_max_target参数大小的限制。
SQL> alter system set memory_max_target=3g scope=spfile; System altered. SQL> alter system set memory_target=3g scope=spfile; System altered. SQL> alter system set sga_max_size=700M scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 730714112 bytes Fixed Size 2230080 bytes Variable Size 310380736 bytes Database Buffers 411041792 bytes Redo Buffers 7061504 bytes Database mounted. Database opened. SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 3G memory_target big integer 3G shared_memory_address integer 0 SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 700M sga_target big integer 0
可以看到将memory_max_target调整到3G,sga_max_size 调整到700M,sga_max_size的大小也没有受到memory_max_target大小的限制。
SQL> alter system set memory_max_target=4g scope=spfile; System altered. SQL> alter system set memory_target=4g scope=spfile; System altered. SQL> alter system set sga_max_size=3800M scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 3975139328 bytes Fixed Size 2232608 bytes Variable Size 1946160864 bytes Database Buffers 2013265920 bytes Redo Buffers 13479936 bytes Database mounted. Database opened. SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 4G memory_target big integer 4G shared_memory_address integer 0 SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 3808M sga_target big integer 0
但是,当将memory_max_target调整为4G,sga_max_size调整为3800M的时候,也就是sga_max_size和memory_max_target大小比较接近的时候,sga_max_size的大小受到了memory_max_target大小的限制,此时ORACLE将sga_max_size的大小设置为3808M。
SQL> alter system set memory_max_target=5g scope=spfile; System altered. SQL> alter system set memory_target=5g scope=spfile; System altered. SQL> alter system set sga_max_size=500M scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 521936896 bytes Fixed Size 2228072 bytes Variable Size 268435608 bytes Database Buffers 243269632 bytes Redo Buffers 8003584 bytes Database mounted. Database opened. SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 5G memory_target big integer 5G shared_memory_address integer 0 SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 500M sga_target big integer 0
将memory_max_target设置为5G,sga_max_size设置为500M,这两个参数的值相差比较大的时候,sga_max_size的大小也没有受memory_max_target大小的限制。
SQL> alter system set memory_max_target=6g scope=spfile; System altered. SQL> alter system set memory_target=6g scope=spfile; System altered. SQL> alter system set sga_max_size=5g scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 5344731136 bytes Fixed Size 2235904 bytes Variable Size 2063598080 bytes Database Buffers 3271557120 bytes Redo Buffers 7340032 bytes Database mounted. Database opened. SQL> show parameter mem NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 6G memory_target big integer 6G shared_memory_address integer 0 SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 5G sga_target big integer 0
此时将memory_max_target调整为6G,sga_max_size调整为5G,sga_max_size也没有受到memory_max_target大小的制约,但是,将memory_max_target和sga_max_size往小调整的时候sga_max_size的大小就会受到memory_max_target大小的制约。
SQL> alter system set memory_max_target=5g scope=spfile; System altered. SQL> alter system set memory_target=5g; System altered. SQL> alter system set sga_max_size=500M scope=spfile; System altered. SQL> startup force ORACLE instance started. Total System Global Area 3841654784 bytes Fixed Size 2259696 bytes Variable Size 637535504 bytes Database Buffers 3191865344 bytes Redo Buffers 9994240 bytes Database mounted. Database opened. SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 3680M sga_target big integer 0
此时将memory_max_target调整为5G,sga_max_size调整为500M,但sga_max_size的实际值ORACLE却自动调整为3680M,至于为什么从大往小调整内存和SGA的大小会有这种制约关系,可能和ORACLE11G最小内存为1G的原则是一样的吧,(有网友发帖说ORACLE11G最少需要1G内存,是为了让只有真正的ORACLE专家才可以玩ORACLE数据库,保证ORACLE的技术力量),我猜想ORACLE的内存管理之所以从大往小调整和这个也有一定的关系,ORACLE不确定当前数据库操作者的技术水平,也就不确定将内存从大往小调整是否会影响数据库的当前性能,为了使ORACLE的运行状态达到最优,从大往小调整就没设置也一些限制,当然这只是我的猜想,没有理论依据。
1. 错别字:注:由于本人较懒,而且实验室(时?)比较匆忙,也是在测试环境下错(作?)的实验
2. 该文测试论断不对:
需要注意的是64位的ORACLE,sga_max_size的大小最小为500M?
可能和ORACLE11G最小内存为1G的原则是一样的吧?
在我自己的虚拟机64位11gR2数据库中,内存都是很小的。你可以去查一下SGA和granule size的关系。
2011-11-20 08:59多谢kamus指点
2012-01-05 01:45