一, 自动共享内存管理介绍
自动共享内存管理ASMM ( 自动共享内存管理, 以下均称 ASMM )是 Oracle 在 10g 版本推出的特性,但是在 11g或 12c 版本中,仍然可以使用 ASMM 来替代自动内存管理 AMM ( 自动内存管理 )。
1. ASMM 概念
从oracle 9i 开始,一些 SGA 参数可以进行动态地修改,通过 “ alter system ” 命令可以放大或缩小他们的当前值。整个SGA 的大小被sga_max_size参数限制。每个一个SGA参数都是以“颗粒”的形式进行分配,这些“颗粒”大小将决定sga_max_size的值和硬件平台。
从9i 版本开始,下面的参数可以动态的定义:
-共享池
-默认缓冲区缓存
-大型泳池
在10g 版本之前,当您想要放大或缩小这些动态参数时,它们的内存不会自动的修改,我们必须手动的进行修改。在 10g 版本中,更新了 ASMM 特性,目的是降低 DBA 对 SGA 的某些组件进行手工修改工作。
当ASMM 启动时,让 Oracle 自动为 SGA 的组件进行正确的分配,如:
-共享池
-大型泳池
-JAVA池
-流池
-DB CACHE(使用DB_BLOCK_SIZE值)
这个功能的主要目地就是, Oracle 根据当前的工作负载分配可用内存。根据内存活动增强内存使用,避免 ORA-4031 这样的内存错误发生。
2. 配置ASMM
自动共享内存管理ASMM 通过一个参数配置: sga_target
当sga_target 设置为 0时 , ASMM将 被扩展。您只能使用更旧的方法去调节内存分配,因此需要自己定义上述自动调节参数。
当设置以下条件, ASMM 将会被启动:
-statistics_level =典型或全部
-sga_target> 0
ASMM 被启用,内存将在所有的组件之间扩展。因此, SGA_TARGET 值将定义可在自动调节参数和手动参数之间共享内存大小。
手动参数如下:
-db_cache_size
-db_nk_cache_size(非默认块大小)
-log_buffer
-固定的sga
-stream_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>显示参数sga_max
名称类型 值
-------------- ----------- ----------------
sga_max_size大整数 300M
如果您想要修改尺寸的sga_target, 将会得到以下错误提示:
SQL> alter system set sga_target = 600m;
更改系统集sga_target = 600m
*
第1行发生错误:
ORA-02097:参数无法修改,因为指定的值无效
ORA-00823:sga_target的指定值大于sga_max_size
二,使用ASMM 示例
1. 手动设置 ASMM
当你刚升级数据库从低版本到10g 版本时,可能会出现以下情况:
sga_target 没有定义,默认为 0
SQL>显示参数sga;
名称类型值
----------------------- ----------- ---------------- --------------
lock_sga布尔值FALSE
pre_page_sga布尔值FALSE
sga_max_size大整数164M
sga_target大整数0
所有SGA 参数已经被手动设置
SQL>显示参数大小
名称 类型值
-------------- ------ - ------- - ----- ----- - --------- ------
bitmap_merge_area_size 整数1048576
create_bitmap_area_size 整数8388608
db_block_size 整数 8192
db_cache_size 大整数 24M
db_keep_cache_size 大整数 0
db_recovery_file_dest_size 大整数 2G
db_recycle_cache_size 大整数 0
db_16k_cache_size 大整数 0
db_2k_cache_size 大整数 0
db_32k_cache_size 大整数 0
db_4k_cache_size 大整数 0
db_8k_cache_size 大整数 0
global_context_pool_size 字符串
hash_area_size 整数 131072
java_max_sessionspace_size 整数 0
java_pool_size 大整数 48M
large_pool_size 大整数 8M
max_dump_file_size 字符串未 限制
object_cache_max_size_percent整数 10
object_cache_optimal_size 整数102400
olap_page_pool_size 大整数 0
parallel_execution_message_size整数 2148
sga_max_size 大整数 164M
shared_pool_reserved_size 大整数 4M
shared_pool_size 大整数 80M
sort_area_retained_size 整数 0
sort_area_size 整数 65536
stream_pool_size 大整数 0
workarea_size_policy 字符串 AUTO
所以,自动调节的参数有
db_cache_size = 24M
shared_pool_size = 80M
large_pool_size = 8M
java_pool_size = 48M
手动设置ASMM 模式
SQL> alter system set sga_target = 100 M;
SQL>显示参数sga;
名称 类型值
--------------------------- ---------- ------------- -------
lock_sga布尔值FALSE
pre_page_sga布尔值FALSE
sga_max_size大整数 164 M
sga_target大整数 164 M
sga_target 作为 sga 的初始值,并且 sga_target 已经自动进行了调整,以支持 V $ SGA_DYNAMIC_COMPONENTS 视图中列出的自动调节参数的初始值。
SQL>从v $ sga_dynamic_components中选择组件,current_size,min_size,user_specified_size;
组件 CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE
--------------------------- ------------ ------- - - --------------------
共用泳池 80 80 80
大型游泳池 8 8 8
Java池 48 48 48
流池 0 0 0
默认缓冲区高速缓存 24 24 24
KEEP缓冲区高速缓存 0 0 0
RECYCLE缓冲区高速缓存 0 0 0
默认2K缓冲区高速缓存 0 0 0
默认4K缓冲区高速缓存 0 0 0
默认8K缓冲区高速缓存 0 0 0
默认16K缓冲区高速缓存 0 0 0
默认32K缓冲区高速缓存 0 0 0
OSM缓冲区高速缓存 0 0 24
在这种情况下, oracle 没有更多空余的内存可以用来进行动态调节。
SQL>从v $ sga_dynamic_free_memory选择*;
目前的规模
------------
0
假设设置sga_max_size 超过 SGA 的计算大小,我们设置为 700M
SQL> alter system set sga_max_size = 300 M scope = spfile;
SQL>立即关闭;
SQL>启动
SQL> alter system set sga_target = 164M;
SQL>显示参数sga;
名称类型值
------------------------------- ----------- -------- ------------
lock_sga布尔值FALSE
pre_page_sga布尔值FALSE
sga_max_size大整数 300M
sga_target大整数 164M
SQL>从v $ sga_dynamic_free_memory中选择current_size / 1024/1024“ CURRENT_SIZE”;
目前的规模
------------
1 36
此时我们发现有140M 的空余内存调用 SGA 使用
2. 增加,减少 sga_target
修改sga_target 大小
SQL> alter system set sga_target = 200M;
SQL>显示参数sga
名称类型 值
------------------------------ ----------- --------- --------------
lock_sga布尔值 FALSE
pre_page_sga布尔值 FALSE
sga_max_size大整数 300 M
sga_target大整数 200 M
SQL>选择组件,来自v $ sga_dynamic_components的current_size / 1024/1024“ CURRENT_SIZE”,min_size / 1024/1024“ MIN_SIZE”,user_specified_size / 1024/1024“ USER_SPECIFIED_SIZE”;
组件 CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE
-------------------------- ------------ ----------- -----------------
共用泳池 80 80 80
大型游泳池 8 8 8
Java池 48 48 48
流池 0 0 0
默认缓冲区高速缓存 60 24 24
KEEP缓冲区高速缓存 0 0 0
RECYCLE缓冲区高速缓存 0 0 0
默认2K缓冲区高速缓存 0 0 0
默认4K缓冲区高速缓存 0 0 0
默认8K缓冲区高速缓存 0 0 0
默认16K缓冲区高速缓存 0 0 0
默认32K缓冲区高速缓存 0 0 0
OSM缓冲区高速缓存 0 0 24
通过上面的对比我们可以看到, DB_BUFFER_CACHE 大小由 24 自动调节到 60 , SGA SIZE = 80M + 8M + 48M + 60M = 196M ,预留 4M 作为手动参数。 甲骨文 将根据内存管理器查出的结果,根据每个自动调节组件的需求来决定在哪里分配更多的空间。
再次进行如下设置
SQL> alter system set sga_target = 300M;
SQL> 选择组件,current_size / 1024/1024“ CURRENT_SIZE”,min_size / 1024/1024“ MIN_SIZE”,
v $ sga_dynamic_components中的user_specified_size / 1024/1024“ USER_SPECIFIED_SIZE”;
组件 CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE
-------------------------- ------------ ----------- -----------------
共用泳池 80 80 80
大型游泳池 8 8 8
Java池 48 48 48
流池 0 0 0
默认缓冲区高速缓存 160 24 24
KEEP缓冲区高速缓存 0 0 0
RECYCLE缓冲区高速缓存 0 0 0
默认2K缓冲区高速缓存 0 0 0
默认4K缓冲区高速缓存 0 0 0
默认8K缓冲区高速缓存 0 0 0
默认16K缓冲区高速缓存 0 0 0
默认32K缓冲区高速缓存 0 0 0
OSM缓冲区高速缓存 0 0 24
如上图所示, db_cache_size已经 提升到了 160。此时 所有添加的 SGA 内存都已经添加了 缓冲区缓存 。
正如上面所言, sga_target 参数包括自动调节和手动参数。当您去提高一个手动参数时,它将影响自动调节部分。
SQL> 更改系统集stream_pool_size = 10M;
SQL> 选择组件,current_size / 1024/1024“ CURRENT_SIZE”,min_size / 1024/1024“ MIN_SIZE”,
user_specified_size / 1024/1024“ USER_SPECIFIED_SIZE”,来自的last_oper_type“ TYPE”
v $ sga_dynamic_components;
组件 CURRENT_SIZE MIN_SIZE SER_SPECIFIED_SIZE类型
------------------------ ------------ ---------- ---- --------------- --------
共享池 80 80 80 STATIC
大游泳池 8 8 8 静态
Java池 48 48 48 静态
溪流池 12 0 12 成长
默认缓冲区高速缓存 148 24 24 SHRINK
KEEP缓冲区高速缓存 0 0 0 静态
循环缓冲区高速缓存 0 0 0 静态
默认2K缓冲区高速缓存 0 0 0 静态
默认4K缓冲区高速缓存 0 0 0 静态
默认8K缓冲区高速缓存 0 0 0 静态
默认16K缓冲区高速缓存 0 0 0 静态
默认32K缓冲区高速缓存 0 0 0 静态
OSM缓冲区高速缓存 0 0 24 静态
如上图所示,我们手动修改了流池 参数,该参数类型转换为 GROW,db_buffer_cache 参数类型转换 SHRINK 。
注意到此处streams pool 是 12M 而不是我们修改的 10M ,是因为 streams pool 基于 GRANULE_SIZE 四舍五入到12M 了。查询 GRANULE_SIZE 基本单位如下:
SQL>选择组件,来自v $ sga_dynamic_components的granule_size / 1024/1024“ GRANULE_SIZE(Mb)”;
成分 GRANULE_SIZE(Mb)
------------------------------ --------------------------------
共享池 4
大泳池 4
Java池 4
溪流池 4
默认缓冲区高速缓存 4
KEEP缓冲区高速缓存 4
RECYCLE缓冲区高速缓存 4
默认2K缓冲区高速缓存 4
默认4K缓冲区高速缓存 4
默认8K缓冲区高速缓存 4
默认16K缓冲区高速缓存 4
默认32K缓冲区高速缓存 4
OSM缓冲区高速缓存 4
也可以通过v $ sga_resize_ops 视图, sga 中组件的历史变化
SQL>选择组件,oper_type,oper_mode,initial_size / 1024/1024“ INITIAL”,
TARGET_SIZE / 1024/1024“ TARGET”,FINAL_SIZE / 1024/1024 “ FINAL”,来自v $ sga_resize_ops的状态;
组件 OPER_TYPE OPER_MODE初始目标最终状态
-------------------- -------- - --------- ------- ---- - ----- ----- - -
DEFAULT缓冲区高速缓存 热收缩手册160 148 148 COMPLETE
流池 GROW手动0 12 12 COMPLETE
如果您打算减少sga_target,则 自动优化的参数将会受到干扰,但是手动参数不会受到干扰。
SQL> alter system set sga_target = 200M;
SQL> 选择组件,来自v $ sga_dynamic_components的current_size / 1024/1024“ CURRENT_SIZE”,min_size / 1024/1024“ MIN_SIZE”,user_specified_size / 1024/1024“ USER_SPECIFIED_SIZE”,last_oper_type“ TYPE”;
组件 CURRENT_SIZE MIN_SIZE SER_SPECIFIED_SIZE类型
------------------------ ------------ ---------- ---- --------------- --------
共享池 80 80 80 STATIC
大游泳池 8 8 8 静态
Java池 48 48 48 静态
溪流池 12 0 12 成长
默认缓冲区高速缓存 48 24 24 缩小
KEEP缓冲区高速缓存 0 0 0 静态
循环缓冲区高速缓存 0 0 0 静态
默认2K缓冲区高速缓存 0 0 0 静态
默认4K缓冲区高速缓存 0 0 0 静态
默认8K缓冲区高速缓存 0 0 0 静态
默认16K缓冲区高速缓存 0 0 0 静态
默认32K缓冲区高速缓存 0 0 0 静态
OSM缓冲区高速缓存 0 0 24 静态
sga_target 在设置的时候,是有一个限制限制。它的预设计算方式为:
SUM(MIN_SIZE)= 所有自动调节参数 + streams_pool 的当前值 + 4M = 176M
如果您的设置值小于这个起点,那么将会报ORA-00827 的错误。
1) 升高,降低自动调节参数
你可以选择去改变一些自动调节参数,如下:
SQL> alter system set shared_pool_size = 100M;
SQL>选择组件,current_size / 1024/1024“ CURRENT_SIZE”,min_size / 1024/1024“
user_specified_size / 1024/1024“ USER_SPECIFIED_SIZE”,来自的last_oper_type“ TYPE”
v $ sga_dynamic_components;
组件 CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE类型
---------------------- ------------ ---------- ------ ------------- -------
共用泳池 100 80 100 成长
大游泳池 8 8 8 静态
Java池 48 48 48 静态
溪流池 12 0 12 成长
默认缓冲区高速缓存 28 24 24 缩小
KEEP缓冲区高速缓存 0 0 0 静态
循环缓冲区高速缓存 0 0 0 静态
默认2K缓冲区高速缓存 0 0 0静态
默认4K缓冲区高速缓存 0 0 0 静态
默认8K缓冲区高速缓存 0 0 0 静态
默认16K缓冲区高速缓存 0 0 0 静态
默认32K缓冲区高速缓存 0 0 0 静态
OSM缓冲区高速缓存 0 0 24静态
上面的查询输出显示shared_pool_size 已经设置为 100M,CURRENT_SIZE 和 USER_SPECIFIED_SIZE 列已经被重置。其中 20M 是从 db_buffer_cache 中 提取的,该列的值从48M 减少到 28M 。
如果你想继续尝试
SQL> alter system set shared_pool_size = 180M;
更改系统集shared_pool_size = 180M
*
第1行发生错误:
ORA-02097:参数
不能修改,因为指定的值无效
ORA-04033:内存不足以增加池
3.ASMM 设置为手动
您可以将ASMM 设置为手动模式, 只要 设置sga_target = 0就可以。
SQL> alter system set sga_target = 0;
在重启实例之后,所有的MIN_SIZE 将会等于 CURRENT_SIZE
SQL>选择组件,current_size / 1024/1024“ CURRENT_SIZE”,min_size / 1024/1024“ MIN_SIZE”,
user_specified_size / 1024/1024“ USER_SPECIFIED_SIZE”,来自的last_oper_type“ TYPE”
v $ sga_dynamic_components;
组件 CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE类型
------------------------- ------------ ---------- --- ---------------- ---- -
共用池 104 104 104 STATIC
大游泳池 8 8 8 静态
Java池 48 48 48 静态
溪流池 12 12 12 静态
默认缓冲区高速缓存 24 24 24 静态
KEEP缓冲区高速缓存 0 0 0 静态
循环缓冲区高速缓存 0 0 0 静态
默认2K缓冲区高速缓存 0 0 0 静态
默认4K缓冲区高速缓存 0 0 0 静态
默认8K缓冲区高速缓存 0 0 0 静态
默认16K缓冲区高速缓存 0 0 0 静态
默认32K缓冲区高速缓存 0 0 0 静态
OSM缓冲区高速缓存 0 0 24 静态
这里需要注意,尽管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为 内存分配做出最佳选择。
- - 结束 - -
文章来源: ITPUB