Oracle性能优化:解释Oracle的自动内存管理(AMM)的机制
2026/7/15 0:47:11 网站建设 项目流程

引言


内存管理一直是Oracle数据库调优中最具挑战性的任务之一。在早期版本中,DBA需要手动分配SGA的各个组件(Buffer Cache、Shared Pool、Large Pool、Java Pool等)以及PGA的大小,这不仅要求对数据库负载有深入理解,还需要根据业务变化频繁调整。一旦配置不当,要么浪费宝贵的内存资源,要么因某个组件过小导致严重的性能问题。


Oracle从11g版本开始引入了自动内存管理(Automatic Memory Management,简称AMM),实现了SGA和PGA的完全自动化管理。本文将深入剖析AMM的工作机制、内部原理、配置方法以及适用场景,帮助你全面理解这一变革性技术。


一、Oracle内存管理架构的演进


在理解AMM之前,有必要回顾Oracle内存管理的发展历程。Oracle的内存管理经历了四个阶段:


手动内存管理
9i及更早

自动PGA管理
9iR2引入

自动SGA管理 ASMM
10g引入

自动内存管理 AMM
11g引入

需手动设置
db_cache_size
shared_pool_size等

设置pga_aggregate_target
Oracle自动分配
各工作区

设置sga_target
Oracle自动分配
SGA各组件

设置memory_target
Oracle自动管理
SGA+PGA整体


1.1 手动内存管理阶段


在9i及更早版本中,DBA需要逐个设置SGA的内存组件参数,例如:


-- 手动管理时代需要设置大量参数 db_block_buffers = 200000 -- Buffer Cache shared_pool_size = 500M -- Shared Pool large_pool_size = 100M -- Large Pool java_pool_size = 50M -- Java Pool sort_area_size = 1048576 -- 排序区 hash_area_size = 2097152 -- 哈希连接区


这种方式的弊端非常明显:

  • 修改参数常常需要重启实例
  • 无法动态响应负载变化
  • 内存利用率低下(一个组件空闲而另一个组件紧张)


1.2 自动PGA管理


9iR2引入了自动PGA管理,通过pga_aggregate_target参数统一控制PGA内存总量,Oracle自动在各个工作区(排序区、哈希区等)之间进行动态分配。


1.3 自动SGA管理(ASMM)


10g引入了ASMM(Automatic Shared Memory Management),通过sga_target参数让Oracle自动管理SGA内部各个组件的分配比例。在ASMM模式下,Buffer Cache、Shared Pool、Large Pool、Java Pool和Streams Pool的大小都可以动态调整,无需人工干预。


1.4 自动内存管理(AMM)


11g最终推出了AMM,将SGA和PGA作为一个整体进行管理。DBA只需要设置一个参数memory_target,Oracle就能在SGA和PGA之间、以及SGA各个子组件之间动态分配内存,实现真正意义上的“全自动内存管理”。


二、AMM的核心机制与工作原理


2.1 关键参数


AMM涉及三个核心参数:


| 参数 | 含义 | 说明 |

|------|------|------|

|memory_target| 内存总目标 | SGA+PGA的总上限,Oracle在此范围内自动分配 |

|memory_max_target| 内存最大目标 |memory_target的动态调整上限,需重启才可修改 |

|sga_target| SGA目标 | 若设置此值,SGA将不小于此值;设为0则完全自动 |

|pga_aggregate_target| PGA目标 | 若设置此值,PGA将不小于此值;设为0则完全自动 |


参数关系memory_max_target >= memory_target >= (sga_target + pga_aggregate_target)


2.2 MMAN进程与自动调整机制


AMM的核心是MMAN(Memory Manager)后台进程。它负责持续监控内存使用情况,并根据负载变化动态调整内存分配。


MMAN后台进程

每60秒周期检查

采集SGA各组件使用率

采集PGA工作区使用率

分析Buffer Cache命中率

分析Shared Pool命中率

分析其他池使用率

分析排序/Hash操作
内存需求

计算各组件
内存边际收益

是否需要重分配?

执行内存转移操作

保持当前分配

从空闲组件回收内存

分配给需求紧张的组件


调整粒度

  • MMAN在每个调整周期中,以颗粒(granule)为单位进行内存转移
  • SGA内部调整的最小单位是一个granule(通常为4MB、8MB或16MB,取决于SGA总大小)
  • SGA与PGA之间的调整则需要更谨慎,通常只有当一侧出现明显瓶颈时才触发


2.3 内存分配与回收的策略


AMM的决策逻辑基于“内存边际效益最大化”原则:


  1. SGA内部调整:MMAN计算各个SGA组件增加单位内存能带来的边际收益(如提高Buffer Cache命中率减少的物理I/O量),将内存从边际收益低的组件转移到边际收益高的组件。


  1. SGA与PGA之间的调整
  • 当PGA紧张(如出现大量multipass sort)且SGA有富余时,将部分内存从SGA转给PGA
  • 当Buffer Cache命中率下降且PGA空闲较多时,将部分内存从PGA转给SGA
  • 这种跨区域调整较为保守,幅度通常较小


  1. 不可收缩的内存
  • 已被应用程序使用的PGA内存不可回收(非共享SQL工作区除外)
  • SGA中的某些组件有最小值限制,不会无限收缩


三、配置AMM的完整步骤


3.1 从手动管理切换到AMM


步骤一:检查当前内存配置


-- 查看当前SGA相关参数 SHOW PARAMETER sga; -- 查看当前PGA相关参数 SHOW PARAMETER pga; -- 查看当前memory相关参数 SHOW PARAMETER memory;


步骤二:计算合适的memory_target


-- 查看当前SGA和PGA实际大小 SELECT ROUND(SUM(bytes)/1024/1024, 2) AS sga_mb FROM v$sgastat; SELECT ROUND(value/1024/1024, 2) AS pga_mb FROM v$pgastat WHERE name = 'maximum PGA allocated'; -- memory_target建议值 = 当前SGA + 当前PGA + 10%余量 -- 但需确保不超过物理内存的60%-70%(留足OS和其他应用的内存)


步骤三:设置AMM参数


-- 1. 设置memory_max_target(需要重启) ALTER SYSTEM SET memory_max_target = 8G SCOPE=SPFILE; -- 2. 重启数据库 SHUTDOWN IMMEDIATE; STARTUP; -- 3. 设置memory_target ALTER SYSTEM SET memory_target = 6G SCOPE=BOTH; -- 4. 将SGA和PGA目标设为0,表示完全自动管理 ALTER SYSTEM SET sga_target = 0 SCOPE=BOTH; ALTER SYSTEM SET pga_aggregate_target = 0 SCOPE=BOTH;


步骤四:验证AMM是否生效


-- 查看AMM状态 SELECT name, ROUND(value/1024/1024, 2) AS value_mb, isdefault FROM v$parameter WHERE name IN ('memory_target', 'memory_max_target', 'sga_target', 'pga_aggregate_target'); -- 查看内存分配详情 SELECT * FROM v$memory_dynamic_components; -- 查看内存调整历史 SELECT component, oper_type, oper_mode, initial_size/1024/1024 AS initial_mb, final_size/1024/1024 AS final_mb, start_time FROM v$memory_resize_ops ORDER BY start_time DESC FETCH FIRST 20 ROWS ONLY;


3.2 从ASMM切换到AMM


如果当前已经使用ASMM(设置了sga_targetpga_aggregate_target),切换更加简单:


-- 1. 设置memory_max_target(需重启) ALTER SYSTEM SET memory_max_target = 10G SCOPE=SPFILE; SHUTDOWN IMMEDIATE; STARTUP; -- 2. 设置memory_target ALTER SYSTEM SET memory_target = 8G SCOPE=BOTH; -- 3. 将sga_target和pga_aggregate_target置零(可选) -- 也可以保留作为最小值控制 ALTER SYSTEM SET sga_target = 0 SCOPE=BOTH; ALTER SYSTEM SET pga_aggregate_target = 0 SCOPE=BOTH;


3.3 混合管理模式


AMM允许设置SGA和PGA的最小值,实现“半自动”管理:


-- memory_target = 8G 总内存 -- sga_target = 4G SGA至少4G -- pga_aggregate_target = 2G PGA至少2G -- 剩下的2G由Oracle根据需要在SGA和PGA之间动态分配 ALTER SYSTEM SET memory_target = 8G SCOPE=BOTH; ALTER SYSTEM SET sga_target = 4G SCOPE=BOTH; ALTER SYSTEM SET pga_aggregate_target = 2G SCOPE=BOTH;


这种模式适用于对SGA或PGA有最低性能要求的场景,既保留了自动管理的灵活性,又能确保关键组件不会缩得过小。


四、AMM的监控与诊断


4.1 关键监控视图


-- 1. v$memory_dynamic_components:查看各内存组件当前大小 SELECT component, ROUND(current_size/1024/1024, 2) AS current_mb, ROUND(min_size/1024/1024, 2) AS min_mb, ROUND(max_size/1024/1024, 2) AS max_mb FROM v$memory_dynamic_components WHERE current_size > 0; -- 2. v$memory_resize_ops:查看最近800次内存调整记录 SELECT component, oper_type, -- GROW/SHRINK oper_mode, -- MANUAL/AUTO/IMMEDIATE/DEFERRED parameter, initial_size/1024/1024 AS init_mb, final_size/1024/1024 AS final_mb, start_time, end_time FROM v$memory_resize_ops ORDER BY start_time DESC FETCH FIRST 30 ROWS ONLY; -- 3. v$sga_resize_ops:SGA内部组件的调整历史 SELECT component, oper_type, initial_size/1024/1024 AS init_mb, target_size/1024/1024 AS target_mb, start_time FROM v$sga_resize_ops ORDER BY start_time DESC FETCH FIRST 20 ROWS ONLY; -- 4. v$memory_target_advice:memory_target大小的建议 SELECT * FROM v$memory_target_advice ORDER BY memory_size;


4.2 判断AMM是否工作良好


健康指标

  • v$memory_resize_ops中有适量的调整记录,说明AMM在动态响应负载变化
  • Buffer Cache和Shared Pool的命中率保持稳定
  • PGA中没有大量multipass executions(多趟排序)


异常信号

  • 某组件频繁被缩小又扩大(内存抖动),说明整体内存不足
  • 看到大量的SHRINK操作且命中率下降,说明memory_target设置过小
  • v$memory_resize_ops中几乎没有记录,说明负载稳定或AMM未启用


五、AMM的优势与局限性


5.1 AMM的四大优势


  1. 简化运维

DBA不再需要为Buffer Cache多大、Shared Pool多大而纠结,大幅降低了调优门槛。


  1. 提高内存利用率

自动按需分配,避免了一个组件空闲而另一个组件饥饿的情况。


  1. 动态适应负载变化

OLTP高峰期自动扩展Buffer Cache,批处理时段自动为PGA分配更多排序空间。


  1. 减少停机时间

内存调整完全在线完成,不需要重启实例。


5.2 AMM的局限性与注意事项


  1. 最大支持内存有限制

在Linux上,AMM通过/dev/shm实现内存共享,/dev/shm的大小通常默认为物理内存的50%,需要手动调整。


```bash

# 查看/dev/shm大小

df -h /dev/shm


# 如需要增大(临时)

mount -o remount,size=16G /dev/shm


# 永久修改,编辑/etc/fstab

tmpfs /dev/shm tmpfs defaults,size=16G 0 0

```


  1. 不支持HugePages

如果系统使用HugePages优化内存管理,则无法使用AMM(HugePages要求预先锁定内存,与AMM的动态分配机制冲突)。此时只能使用ASMM配合手动PGA管理。


  1. 极端负载下调整滞后

MMAN每60秒调整一次,对于突发性的极端负载变化,可能响应不够快。


  1. 调整幅度保守

为了稳定性,AMM的调整策略偏保守,SGA与PGA之间的内存转移通常较慢。


  1. 多实例环境下需谨慎

在单服务器上运行多个Oracle实例时,各实例的AMM彼此独立,可能导致总内存超分,需要全局规划。


六、AMM vs ASMM:如何选择?


负载稳定多实例

选择内存管理方式

是否使用HugePages?

使用ASMM + 手动PGA
禁用AMM

是否为单实例?

负载波动大吗?

推荐AMM
全自动管理

ASMM + 手动PGA
或AMM均可

能否精确规划
各实例内存?

每实例用AMM
设memory_target上限

使用ASMM + PGA
逐实例精确控制


一般建议

  • 中小型数据库、负载波动明显的场景:优先使用AMM
  • 大型OLTP、需要使用HugePages:使用ASMM + 手动PGA
  • RAC环境:每个节点独立配置AMM,但需注意总内存上限


七、实战案例:AMM解决内存争用问题


场景:某零售系统白天OLTP业务需要大量Buffer Cache,夜间跑批需要大量PGA进行排序和Hash Join。之前手动配置SGA 4G、PGA 1G,白天Buffer Cache紧张,夜间PGA不足。


优化方案:启用AMM,总内存设为8G


-- 设置memory_max_target并重启 ALTER SYSTEM SET memory_max_target = 8G SCOPE=SPFILE; SHUTDOWN IMMEDIATE; STARTUP; -- 启用AMM ALTER SYSTEM SET memory_target = 8G SCOPE=BOTH; ALTER SYSTEM SET sga_target = 0 SCOPE=BOTH; ALTER SYSTEM SET pga_aggregate_target = 0 SCOPE=BOTH;


验证效果


-- 白天的内存分布(AMM自动偏向SGA) -- Buffer Cache: 约4.5G -- Shared Pool: 约1G -- PGA: 约1.5G -- 夜间的内存分布(AMM自动偏向PGA) -- Buffer Cache: 约2.5G -- Shared Pool: 约800M -- PGA: 约3.7G


优化效果

  • 白天Buffer Cache命中率从87%提升至96%
  • 夜间批处理时间缩短35%(PGA充足,减少了磁盘排序)
  • 无需人工干预,内存随业务节奏自动调整


八、总结与建议


  1. AMM是Oracle内存管理的集大成者,将DBA从繁琐的参数调优中解放出来,实现了SGA和PGA的整体自动化管理。


  1. 核心机制是通过MMAN后台进程,基于“边际效益最大化”原则,以granule为单位持续动态调整各内存组件的分配。


  1. 配置AMM的关键三步:设置memory_max_target(需重启)、设置memory_target、将sga_targetpga_aggregate_target置零或设为最小值。


  1. 不能迷信AMM:使用HugePages的场景、需要极端确定性内存分配的场景,仍应选择ASMM或手动管理。


  1. 持续监控v$memory_resize_opsv$memory_dynamic_components,确保AMM的调整行为符合预期。


调优箴言:自动内存管理不是“放任不管”,而是将DBA的精力从琐碎的内存数字游戏中解放出来,转而关注更重要的SQL优化和架构设计。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询