启用AMM后,_SGA和_PGA为只读参数,手动设置会导致启动失败或ORA-00843错误;应配置memory_target和memory_max_target,并确保Linux的memlock限制已解除。
Oracle 11g+ 用 AMM 就别碰 _SGA 和 _PGA 这两个隐藏参数
amm(automatic memory management)启用后,_sga 和 _pga 是 oracle 内部自动推导的只读值,手动设它们不仅无效,还会让实例启动失败或触发 ora-00843 错误。你看到的 show parameter sga 结果里那些带下划线的参数,是诊断用的快照,不是配置入口。
真正该配的是 memory_target 和 memory_max_target —— 它们才是 AMM 的开关和天花板:
-
memory_max_target必须在实例未启动时通过spfile设置,改了要重启 -
memory_target可在线调整(只要不超过memory_max_target),但调整后 SGA/PGA 重分配需要几秒,期间可能观察到短时性能抖动 - 如果数据库已启用了 ASMM(
sga_target> 0 且pga_aggregate_target> 0),再开 AMM 会报 ORA-00852,必须先清空这两个参数
ORA-00843: “SGA size cannot be set to zero” 是 AMM 配错最常见报错
这个错误不是内存真不够,而是参数冲突的信号灯。典型触发场景:你把 sga_target=0 或 pga_aggregate_target=0 留在 spfile 里,又开了 AMM;或者误把 memory_target 设成 0。
查错路径很直接:
- 连上去就报错?立刻查
show parameter memory和show parameter sga,看有没有残留的 ASMM 参数 - 用
strings $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora | grep -i "sga\|pga\|memory"扫一遍真实 spfile 内容,隐藏参数也可能藏在里面 - 确认
memory_target值大于 0,且memory_max_target≥ 它;若不确定,先删掉 spfile 里的sga_target、pga_aggregate_target行,再重启
Linux 上开启 AMM 要关掉 memlock 限制,否则 ORA-27102 出来就卡死
AMM 依赖 mmap(MAP_HUGETLB) 分配大页内存,而 Linux 默认对普通用户锁内存大小有限制(ulimit -l)。Oracle 启动时发现锁不住,就报 ORA-27102: “out of memory” —— 实际物理内存充足,只是被系统拦住了。
解决它不靠调 Oracle 参数,得改系统层:
- 编辑
/etc/security/limits.conf,加两行:oracle soft memlock unlimitedoracle hard memlock unlimited - 确认
oracle用户登录后执行ulimit -l返回unlimited,不是数字或65536 - 注意:RHEL/CentOS 7+ 若启用了
systemd,还要检查/etc/systemd/system/oracle.service里是否覆盖了LimitMEMLOCK,否则 limits.conf 不生效
AMM 在 OLTP 和 DSS 混合负载下容易“偏科”,别指望它永远聪明
AMM 的算法倾向把内存多分给 SGA(尤其是 buffer cache),因为它的收益更容易被统计到;PGA(排序、哈希区)增长靠 SQL 执行时动态申请,一旦并发高、SQL 复杂,PGA 突然吃紧,AMM 反应慢半拍,可能触发大量临时表空间写入或直接报 ORA-04030。
监控重点不是总内存够不够,而是实时分布:
- 查
v$memory_dynamic_components,看current_size列里shared pool、buffer cache、pga_aggregate_target三者是否此消彼长明显 - 结合
v$pgastat的total PGA allocated和over allocation count,后者非零就说明 PGA 已经透支过一次 - 如果业务以复杂报表为主,宁可关 AMM、切回 ASMM,并把
pga_aggregate_target设为总内存的 30%~40%,比 AMM 自动分的更稳
AMM 真正省心的地方是小库、低并发、SQL 类型单一的场景;一遇到混合负载或突发查询,它那套基于历史统计的分配逻辑,反应不过来。










