一,  自动共享内存管理介绍

自动共享内存管理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       

Java池       48     48   48

流池     0         

默认缓冲区高速缓存   24     24   24

KEEP缓冲区高速缓存     0         

RECYCLE缓冲区高速缓存   0         

默认2K缓冲区高速缓存   0         

默认4K缓冲区高速缓存   0         

默认8K缓冲区高速缓存   0         

默认16K缓冲区高速缓存   0         

默认32K缓冲区高速缓存    0 0       

OSM缓冲区高速缓存     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

Java池     48     48   48

流池           0

默认缓冲区高速缓存   60     24   24

KEEP缓冲区高速缓存         0

RECYCLE缓冲区高速缓存         0

默认2K缓冲区高速缓存       0

默认4K缓冲区高速缓存       0

默认8K缓冲区高速缓存       0

默认16K缓冲区高速缓存       0

默认32K缓冲区高速缓存       0

OSM缓冲区高速缓存         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

Java池     48     48   48

流池           0

默认缓冲区高速缓存   160 24 24        

KEEP缓冲区高速缓存         0

RECYCLE缓冲区高速缓存         0

默认2K缓冲区高速缓存       0

默认4K缓冲区高速缓存       0

默认8K缓冲区高速缓存       0

默认16K缓冲区高速缓存       0

默认32K缓冲区高速缓存       0

OSM缓冲区高速缓存         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     静态

Java池     48   48   48     静态

溪流池     12     12     成长

默认缓冲区高速缓存   148   24   24     SHRINK

KEEP缓冲区高速缓存       0     静态

循环缓冲区高速缓存       0     静态

默认2K缓冲区高速缓存     0     静态

默认4K缓冲区高速缓存     0     静态

默认8K缓冲区高速缓存     0     静态

默认16K缓冲区高速缓存     0     静态

默认32K缓冲区高速缓存     0     静态

OSM缓冲区高速缓存       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手动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     静态

Java池     48   48   48     静态

溪流池     12     12     成长

默认缓冲区高速缓存   48   24   24     缩小

KEEP缓冲区高速缓存       0     静态

循环缓冲区高速缓存       0     静态

默认2K缓冲区高速缓存     0     静态

默认4K缓冲区高速缓存     0     静态

默认8K缓冲区高速缓存     0     静态

默认16K缓冲区高速缓存     0     静态

默认32K缓冲区高速缓存     0     静态

OSM缓冲区高速缓存       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     静态

Java池     48     48 48     静态

溪流池     12     12     成长

默认缓冲区高速缓存   28     24 24     缩小

KEEP缓冲区高速缓存       0     静态

循环缓冲区高速缓存       0     静态

默认2K缓冲区高速缓存 0静态          

默认4K缓冲区高速缓存     0     静态

默认8K缓冲区高速缓存     0     静态

默认16K缓冲区高速缓存     0     静态

默认32K缓冲区高速缓存     0     静态

OSM缓冲区高速缓存   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     静态

Java池     48   48   48     静态

溪流池     12   12   12     静态

默认缓冲区高速缓存   24   24   24     静态

KEEP缓冲区高速缓存       0     静态

循环缓冲区高速缓存       0     静态

默认2K缓冲区高速缓存     0     静态

默认4K缓冲区高速缓存     0     静态

默认8K缓冲区高速缓存     0     静态

默认16K缓冲区高速缓存     0     静态

默认32K缓冲区高速缓存     0     静态

OSM缓冲区高速缓存       24     静态

这里需要注意,尽管memory_target  sga_target 参数设置为 ,自动内存管理( AMM / ASMM )已经替换,但是升级到 11.2 版本之后, SGA 的大小可能会重新调整,这通常表现在 share_pool_size 增加,而剩余的 db_cache_size值减少 。db_cache_size 可能会缩小到参数文件中指定的 db_cache_size 值以下。

三,总结

10g 以前的版本中,可以通过为 SGA 的各个组件找到最佳的值,来达到实例调优。使用 ASMM ,我们不必调整一些SGA 组件参数的大小, oracle 会根据实例概要来自动选择正确的值。 Oracle 建议为这些自动调优的参数提供一个最小的显式设置,来帮助 Oracle为 内存分配做出最佳选择。

 

- - 结束 - -