MEMORY_TARGET未生效是因为SGA_TARGET和PGA_AGGREGATE_TARGET未同时设为0,否则Oracle退回到ASMM或混合模式;修改后需重启实例。
MEMORY_TARGET 设置后为什么没生效?
amm 不是设了 memory_target 就自动跑起来的——它有硬性前提:必须同时把 sga_target 和 pga_aggregate_target 都设为 0。否则 oracle 会退回到 asmm(只管 sga)或混合模式,amm 实际被禁用。
- 检查当前值:
SHOW PARAMETER sga_target、SHOW PARAMETER pga_aggregate_target,两个都得是0 - 如果它们非零,哪怕
MEMORY_TARGET已设,Oracle 也会忽略 AMM,只按传统方式分配 - 修改后必须重启实例才生效(因为
SGA_TARGET/PGA_AGGREGATE_TARGET是静态参数)
MEMORY_MAX_TARGET 到底要不要设?怎么设?
要设,而且建议显式设。不设的话,Oracle 会在启动时把 MEMORY_MAX_TARGET 自动设成和 MEMORY_TARGET 相同的值——这等于锁死了上限,后续想动态调大 MEMORY_TARGET 就只能重启。
- 典型做法:留 20%~30% 余量,比如目标内存 8G,就设
MEMORY_MAX_TARGET=10G -
MEMORY_MAX_TARGET是静态参数,改完必须SHUTDOWN IMMEDIATE; STARTUP; - 设得太小(比如只比
MEMORY_TARGET大 100MB),看似省内存,实则失去弹性,负载突增时容易触发内存争抢
OLTP 和 DSS 场景下 MEMORY_TARGET 怎么估算?
别直接拍脑袋填 4G 或 16G。真实可用内存取决于物理内存、系统开销、其他进程占用,再叠加上 Oracle 自身对 PGA 的“突发需求”。
- 专用数据库服务器上,先取物理内存的 70%~80%,作为 Oracle 可用总内存基线
- OLTP 系统:PGA 波动小,
MEMORY_TARGET≈ 上述基线 × 0.9(留点给 OS 和日志缓冲区等) - DSS/报表类:查大表、排序多,PGA 峰值可能冲高,建议从
SELECT value FROM v$pgastat WHERE name = 'maximum PGA allocated'查历史峰值,再加 20% 安全边距 - 重做日志缓冲区(
LOG_BUFFER)永远不受 AMM 管控,如果业务写日志频繁,需单独评估是否要手动加大
开启 AMM 后性能反而变差?常见诱因
AMM 不是银弹。它靠后台进程 MMAN 动态调节,但调节有延迟、有粒度限制,某些场景下“自动”反而成了瓶颈。
- 大量临时表 + 排序操作:AMM 可能慢半拍,PGA 不够用时触发磁盘排序(
disk sort),看v$sysstat中sorts (disk)是否陡增 - 内存碎片化严重(尤其在长期运行未重启的实例中):AMM 分配的是连续共享内存段,OS 层若碎片多,
MEMORY_TARGET设再大也申请不到 - Linux 下未关闭
transparent_hugepage:与 AMM 内存映射机制冲突,导致周期性卡顿,必须关掉 - 启用了 AMM 却还手动调
DB_CACHE_SIZE或SHARED_POOL_SIZE:这些参数会被 AMM 覆盖,徒增混乱
AMM 最容易被忽略的一点:它只管“总量”,不管“分布”。当某类操作(比如并行查询、RMAN 备份)突然吃掉大量 PGA,而 SGA 缓冲池被压缩过度,热块就容易反复进出内存——这种抖动不会报错,但响应时间会悄悄变长。










