MEMORY_TARGET在Oracle 19c中常不生效,主因是/dev/shm容量不足或存在SGA_TARGET等冲突参数;须确保/dev/shm≥MEMORY_TARGET、清空显式内存参数、设置MEMORY_MAX_TARGET并重启,且AMM无法运行时切换。
为什么 MEMORY_TARGET 在 Oracle 19c 里经常“不生效”
oracle 19c 默认启用自动内存管理(amm),但实际中 memory_target 常被系统忽略,表现为 sga/pga 手动配置项仍起作用、v$memory_dynamic_components 显示组件大小不变、甚至启动时报 ora-00845: memory_target not supported on this system。根本原因不是参数写错,而是底层限制没满足——linux 的 /dev/shm 容量必须 ≥ memory_target 值,且数据库必须以 amm 模式启动(即未设置 sga_target 或 pga_aggregate_target 等显式值)。
实操建议:
- 检查
/dev/shm大小:df -h /dev/shm;若小于MEMORY_TARGET,需在/etc/fstab中追加tmpfs /dev/shm tmpfs size=4G,mode=1777 0 0并mount -o remount /dev/shm - 确认无冲突参数:
SHOW PARAMETER sga_target和SHOW PARAMETER pga_aggregate_target必须返回空值或 0,否则 AMM 被禁用 -
MEMORY_MAX_TARGET必须 ≥MEMORY_TARGET,且只能在spfile中修改后重启生效,不能动态设
如何安全地从手动内存切换到 MEMORY_TARGET 自动管理
直接 ALTER SYSTEM SET MEMORY_TARGET = ... 往往失败,因为 Oracle 不允许运行时从手动模式(ASMM)切到 AMM。必须先清空所有显式内存组件控制参数,再重启。
实操建议:
- 查当前是否为 ASMM:
SELECT component, current_size FROM V$MEMORY_DYNAMIC_COMPONENTS—— 若有非零值,说明正走 ASMM 路径 - 停库前执行:
ALTER SYSTEM RESET sga_target SCOPE=SPFILE、ALTER SYSTEM RESET pga_aggregate_target SCOPE=SPFILE、ALTER SYSTEM RESET memory_max_target SCOPE=SPFILE(如有) - 在
spfile中只保留:memory_target = 4G、memory_max_target = 4G(建议二者相等,避免后续扩容陷阱) - 重启后验证:
SELECT name, value FROM V$PARAMETER WHERE name IN ('memory_target','sga_target','pga_aggregate_target')—— 后两者应为 0
V$MEMORY_TARGET_ADVICE 的真实用途和常见误读
这个视图常被当成“调优向导”,但它只反映 SGA+PGA 总量变化对 ESTD_DB_TIME 的模拟影响,并不考虑 OS 内存压力、swap 使用或并发负载突变。它不会告诉你该设多少,只会说“如果设成 X,预计 DB Time 会降 Y%”——前提是其他条件不变。
实操建议:
- 别依赖它定初始值:生产环境首次启用
MEMORY_TARGET,应基于历史 AWR 报告中SGA + PGA峰值之和上浮 20%,而非视图推荐值 - 查询时加过滤:
SELECT * FROM V$MEMORY_TARGET_ADVICE WHERE memory_size_factor = 1.2(看比当前高 20% 的预测) - 注意时效性:该视图数据每小时刷新一次,且仅在
STATISTICS_LEVEL = TYPICAL或ALL时收集
为什么 MEMORY_TARGET 设太高反而导致 OOM Killer 杀掉 Oracle 进程
Linux 内核看到 Oracle 进程申请大量共享内存(shmget),但未真正使用,仍会计入进程 RSS。当物理内存吃紧时,OOM Killer 可能优先干掉这个“看着最能吃”的进程——即使 Oracle 实际只用了其中一小部分。
实操建议:
- 监控真实内存占用:
ipcs -m查共享内存段大小,pmap -x <oracle_pid>看 RSS vs SIZE - 设置保守上限:不要把
MEMORY_TARGET直接拉到物理内存的 70%,留足给 OS、备份进程、RMAN 等;19c 单实例建议 ≤ 50% - 配合内核参数:
vm.overcommit_memory = 2+vm.overcommit_ratio = 80,避免因 overcommit 拒绝大内存分配
AMM 的弹性是假象,底层仍是静态共享内存段。真正动态的是 Oracle 内部组件间的水位线调整,不是 OS 级别的按需分配。这点容易被文档带偏。










