一、自动共享内存管理介绍
自动共享内存管理ASMM(Automatic Shared Memory Management,以下均称ASMM)是Oracle在10g版本推出的特性,但是在11g或12c版本,仍然可以用ASMM来替代自动内存管理AMM(Automatic Memory Management)。
1.ASMM概念
从oracle 9i开始,一些SGA参数可以进行动态地修改,通过”alter system”命令可以放大或缩小他们的当前值。整个SGA的大小被sga_max_size参数限制。每一个SGA参数都是以“颗粒”的形式进行分配,这些“颗粒”大小将取决于sga_max_size的值和硬件平台。
从9i版本开始,下面的参数可以动态的定义:
Shared Pool
Default Buffer Cache
Large Pool
在10g之前版本,当你想要放大或缩小这些动态参数,空闲的内存不会自动的修改,我们必须手动的进行修改。在10g版本,引入了ASMM特性,目的是减轻DBA对SGA的某些组件进行手工修改工作。
当ASMM启动时,让Oracle自动为SGA的组件进行正确的分配,如:
SHARED POOL
LARGE POOL
JAVA POOL
STREAMS POOL
DB CACHE(using the DB_BLOCK_SIZE value)
这个功能的主要目地就是,Oracle根据当前的工作负载分配可用内存。根据内存活动增强内存使用,避免ORA-4031这样的内存错误发生。
2.配置ASMM
自动共享内存管理ASMM通过一个参数配置:sga_target
当sga_target设置为0,ASMM将会被禁用。你只能用更旧的方法去调节内存分配,因此需要自己定义上述自动调节参数。
当设置以下条件,ASMM将会被启动:
statistics_level=typical or all
sga_target > 0
ASMM被启用,内存将在所有的组件之间扩展。因此,sga_target值将定义可在自动调节参数和手动参数之间共享内存大小。
手动参数如下:
db_cache_size
db_nk_cache_size(non default block size)
log_buffer
fixed sga
streams_pool_size
在这些手动参数中,有一些是可修改的,有一些是固定的(仅在启动时固定)
可修改的:db_cache_size,streams_pool_size
固定的:db_nk_cache_size,fixed sga,log_buffer
sga_target值被sga_max_size值限制,sga_max_size参数不能动态修改。
SQL> show parameter sga_max
NAME TYPE VALUE
-------------- ----------- ----------------
sga_max_size big integer 300M
如果你想要修改更大的sga_target,将会得到以下错误提示:
SQL> alter system set sga_target=600m;
alter system set sga_target=600m
*
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
二、使用ASMM示例
1.手动设置ASMM
当你刚升级数据库从低版本到10g版本时,可能会出现以下情况:
sga_target没有定义,默认为0
所有SGA参数已经被手动设置
所以,自动调节的参数有
db_cache_size=24M
shared_pool_size=80M
large_pool_size=8M
java_pool_size=48M
手动设置ASMM模式
SQL> alter system set sga_target=100M;
SQL> show parameter sga;
NAME TYPE VALUE
--------------------------- ---------- --------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 164M
sga_target big integer 164M
sga_target作为sga的最小值,并且sga_target已经自动做了调整,以支持V$SGA_DYNAMIC_COMPONENTS视图中列出的自动调节参数的初始值。
SQL> select component, current_size, min_size, user_specified_size from v$sga_dynamic_components;
在这种情况下,oracle没有更多空余的内存可以用来进行动态调节。
SQL> select * from v$sga_dynamic_free_memory;
CURRENT_SIZE
------------
0
假设设置sga_max_size超过SGA的计算大小,我们设置为700M
SQL> alter system set sga_max_size=300M scope=spfile;
SQL> shutdown immediate;
SQL> startup
SQL> alter system set sga_target=164M;
SQL> show parameter sga;
NAME TYPE VALUE
------------------------------- ----------- --------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 300M
sga_target big integer 164M
SQL> select current_size/1024/1024 "CURRENT_SIZE" from v$sga_dynamic_free_memory;
CURRENT_SIZE
------------
136
此时我们发现有140M的空余内存可供SGA使用
2.增加、减少sga_target
修改sga_target大小
SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE", user_specified_size/1024/1024 "USER_SPECIFIED_SIZE" from v$sga_dynamic_components;
通过上面的对比我们可以看到,db_buffer_cache大小由24自动调节到60,SGA SIZE=80M+8M+48M+60M=196M,预留4M作为手动参数。Oracle将根据内存管理器查出的结果,根据每个自动调节组件的需求来决定在哪里分配更多的空间。
再次进行如下设置
SQL> alter system set sga_target=300M;
SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",
user_specified_size/1024/1024 "USER_SPECIFIED_SIZE" from v$sga_dynamic_components;
如上图所示,db_cache_size已经提升到了160。此时所有添加的SGA内存都已经添加给buffer cache。
正如上面所言,sga_target参数包括自动调节和手动参数。当你去提高一个手动参数时,它将会影响自动调节部分。
SQL> alter system set streams_pool_size=10M;
SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",
user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from
v$sga_dynamic_components;
如上图所示,我们手动修改了streams pool参数,该参数类型变为GROW,db_buffer_cache参数类型变为SHRINK。
注意到这里streams pool是12M而不是我们修改的10M,是因为streams pool基于GRANULE_SIZE四舍五入到12M了。查询GRANULE_SIZE基本单位如下:
SQL> select component, granule_size/1024/1024 "GRANULE_SIZE(Mb)" from v$sga_dynamic_components;
COMPONENT GRANULE_SIZE(Mb)
------------------------------ ----------------
shared pool 4
large pool 4
java pool 4
streams pool 4
DEFAULT buffer cache 4
KEEP buffer cache 4
RECYCLE buffer cache 4
DEFAULT 2K buffer cache 4
DEFAULT 4K buffer cache 4
DEFAULT 8K buffer cache 4
DEFAULT 16K buffer cache 4
DEFAULT 32K buffer cache 4
OSM Buffer Cache 4
也可以通过v$sga_resize_ops视图,sga中组件的历史变化
SQL> select component, oper_type, oper_mode,initial_size/1024/1024 "INITIAL",
TARGET_SIZE/1024/1024 "TARGET", FINAL_SIZE/1024/1024 "FINAL", status from v$sga_resize_ops;
如果你打算减少sga_target,自动优化的参数将会受影响,但是手动参数不会受影响。
SQL> alter system set sga_target=200M;
SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE", user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from v$sga_dynamic_components;
sga_target在设置的时候,是有一个最小值限制。它的最小值计算方式为:
SUM(MIN_SIZE)= 所有自动调节参数 + streams_pool的当前值 + 4M = 176M
如果你的设置值小于这个最小值,那么将会报ORA-00827的错误。
1)升高、降低自动调节参数
你可以选择去改变一些自动调节参数,如下:
SQL> alter system set shared_pool_size=100M;
SQL>select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "
user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from
v$sga_dynamic_components;
上面的查询输出显示shared_pool_size已经设置为100M,CURRENT_SIZE和USER_SPECIFIED_SIZE列已经被重置。其中20M是从db_buffer_cache中提取的,该列的值从48M减少到28M。
如果你想继续尝试
SQL> alter system set shared_pool_size=180M;
alter system set shared_pool_size=180M
*
ERROR at line 1:
ORA-02097: param
eter cannot be modified because specified value is invalid
ORA-04033: Insufficient memory to grow pool
3.ASMM设置为手动
你可以禁用ASMM设置为手动模式,只要设置sga_target=0即可。
SQL> alter system set sga_target=0;
在重启实例之后,所有的MIN_SIZE将会等于CURRENT_SIZE
SQL> select component, current_size/1024/1024 "CURRENT_SIZE", min_size/1024/1024 "MIN_SIZE",
user_specified_size/1024/1024 "USER_SPECIFIED_SIZE", last_oper_type "TYPE" from
v$sga_dynamic_components;
这里需要注意,尽管memory_target和sga_target参数设置为0,自动内存管理(AMM/ASMM)已经禁用,但是升级到11.2版本之后,SGA的大小可能会重新调整,这通常表现在share_pool_size增加,而剩余的db_cache_size值减少。db_cache_size可能会缩小到参数文件中指定的db_cache_size值以下。
三、总结
在10g以前的版本,可以通过为SGA的各个组件找到最佳的值,来达到实例调优。使用ASMM,我们不必调整一些SGA组件参数的大小,oracle会根据实例概要来自动选择正确的值。Oracle建议为这些自动调优的参数提供一个最小显式设置,来帮助Oracle对于内存分配做出最佳选择。
---- end ----