大家好,又见面了,我是你们的朋友全栈君。
ASMM(Automatic Shared Memory Management,自动共享内存管理)是Oracle 10g引入的概念。通过使用ASMM,就不需要手工设置相关内存组件的大小,而只为SGA设置一个总的大小,
Oracle的MMAN进程(Memory Manager Process,内存管理进程)会随着时间推移,根据系统负载的变化和内存需要,自动调整SGA中各个组件的内存大小。
ASMM的SGA中包含的组件及对应参数如下表所示:
在
MOS SGA and PGA Management in 11g’s Automatic Memory Management (AMM) (ID 1392549.1)AMMASMM 每一个Oracle的初学者在入门阶段都会接触到SGA/PGA的知识,如果是从10g开始学习那么会多或少会对ASMM有所了解,从使用的角度来说ASMM的出现极大地简化了Oracle内存初始化参数的设置,在ASMM的使用上高级DBA和初学者不会有太大的差别;很多人因此而认为ASMM极大程度地减少了数据库对于专业DBA的依赖:如果我们有一个足够智能的DB,那么为什么还要花费金钱雇佣DBA呢?这似乎是时下一种十分流行的想法。当然这种想法我个人是不能苟同的,ASMM一定程度上带来了便利,更大程度上它是一个黑盒,黑盒里面藏了很多秘密,这些秘密带来比手动管理更多的不确定性;在10g release 1和10.2的早期版本中ASMM扮演的角色有点像一个闯祸精,另一个让用户对ASMM很不待见的原因是ASMM直接拖慢了startup的速度。一个个人观点是ASMM也好AMM也罢,都要求产品数据库DBA掌握更多SGA/PGA相关的知识才能成功”驾驭”这些”有智力”的家伙,有点夸张的说这个时候的DBA很像一个chemist(需要和一大堆以1个或2个下划线开头的奇怪参数打交道)。
Oracle的SGA基本内存组件从9i开始并没有非常大的变化,他们包括:
- 在9i中尚未引入ASMM,唯一的选择是手动管理的SGA,有时候也叫做MSMM。在9i中除去buffer cache的大小可以手动修改外,其余组件都无法动态修改。因为缺乏一种动态管理的机制,所以在9i中如果有某个内存区域有急用,也无法从其他有空闲内存的组件中捐献一些来解燃眉之急。
- 个别组件如shared pool、default buffer pool的大小存在最优值,但组件之间无法交换内存
- 在9i中就提供了多种内存建议(advisor),但都要求人工手动干预
- 无法适应工作负载存在变化的环境
- 往往会导致内存浪费,没有用到实处
- 若设置不当,引发著名的ORA-04031错误的可能性大大提高
- 全自动的共享内存管理
- 无需再配置每一个内存组件大小参数
- 仅使用一个参数sga_target驱动
- 有效利用所有可用的内存,极大程度上减少内存浪费
- 对比MSMM其内存管理模式:
- 更加动态
- 更加灵活
- 并具备适应性
- 易于使用
- 一定程度上增强了性能,因为内存分配更为合理了
- 当某个组件急需更多内存时可以有效提供,因此可以一定程度避免ORA-04031的发生
ASMM下一部分参数是自动设置的(Automatically set),这些参数包括:shared_pool_size、db_cache_size、java_pool_size、large_pool _size和streams_pool_size;而另外一些是需要手动设置的静态参数,包括了:db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size、log_buffer以及固定SGA内存结构等,如果以上没有手动设置这些参数的话,除去log_buffer和fixed sga其他内存组件一般默认大小为零。
SQL> show parameter sga NAME TYPE VALUE ———————————— ———– —————————— lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 2000M sga_target big integer 2000M SQL> show parameter sga_target NAME TYPE VALUE ———————————— ———– —————————— sga_target big integer 2000M SQL> alter system set statistics_level=BASIC; alter system set statistics_level=BASIC * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00830: cannot set statistics_level to BASIC with auto-tune SGA enabled
G10R2.__db_cache_size=973078528 G10R2.__java_pool_size=16777216 G10R2.__large_pool_size=16777216 G10R2.__shared_pool_size=1006632960 G10R2.__streams_pool_size=67108864
在ASMM的内存交换模型中存在三类组件
立即内存申请(Immediate Request):这种申请模式一般出现在ASMM管理的某个自动调优组件在无法分配到连续可用内存块(chunk)时,为了避免出现OUT-OF-MEMORY(ORA-04031)的错误,系统尝试从其他候选组件中转移一个内存颗粒(granule)过来。需要注意的是当前可能没有可用的全空granule,这时就会出现不完整的转移,在此情形下系统会开始从候选组件中清理内存颗粒以满足内存申请,并将一个granule不完整地转移给急需内存的组件。
手动内存申请(Manual Request):这种申请仅发生在用户使用alter system命令手动调整内存组件的大小时。在这种模式下仅允许使用空的内存颗粒参与大小调整。如果当时没有足够的空granule,那么针对组件grow操作会返回ORA-4033错误,而针对组件shrink操作会返回ORA-4034错误。
当ASMM被启用后,内存代理(Memory Broker)定期执行上图所示的活动。以上操作都处于延迟内存申请模式下(Deferred)。其目的是通过自动化的作业来调优自动调优组件(auto-tunable component)的大小以适应不断改变的工作负载,将内存分配到最需要它们的地方。MMON辅助进程会在后台不断将统计信息和内存建议定期地捕获到循环使用的内存中,并计算不同时期缓存信息之间的差值;MMON还会基于Memory Broker的策略分析这些差值并估算出长期和短期内的趋势。最后MMON基于以上分析生成一些内存组件的大小调整决议并将相应的申请发送到一个系统申请队列中(resize request system queue)。MMAN后台进程(Memory Manager is a background process that manages the dynamic resizing of SGA memory areas as the workload increases or decreases)会定期扫描系统申请队列并执行内存转移。
当某个组件扮演捐献者(Donor,下面的trace中会看到)角色时,它可能将一个不完整granule转移给buffer cache,那么在该granule被使用前需要完成以下步骤:
- 接着我们来了解一下内存转移的基本原理,当将buffer cache中的granule转移给shared pool时,将按照以下步骤:
- 实际使用中ASMM受到众多隐藏参数的影响,其中比较主要的参数有:
Level |
Contents |
0x01 |
Enables statistics tracing |
0x02 |
Enables policy tracing |
0x04 |
Enables transfer of granules tracing |
0x08 |
Enables startup tracing |
0x10 |
Enables tuning tracing |
0x20 |
Enables cache tracing |
接下来我们通过设置_memory_management_tracing隐藏参数和DUMP_TRANSFER_OPS转储来实地了解一次完整的内存转移,和不完整的内存转移。以下演示的完整trace文件可以从这里下载 mman_trace 、 transfer_ops_dump 。
以下为一个完整granule转移的过程,包括了对default buffer pool的resize操作:
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/133838.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...