shmmax必须≥单实例最大sga(如12gb),shmall必须≥所有实例sga总和÷页大小(通常4kb)并向上取整,否则多实例启动时因超出内核共享内存硬限而直接报ora-27123或ora-27102失败。

多实例 Oracle 服务器上,共享内存段配置不合理会直接导致实例启动失败、SGA 分配卡死,或系统级内存争用——这不是性能问题,而是启动即崩溃的硬性限制。
为什么 shmmax 和 shmall 必须按总 SGA 需求计算?
Linux 内核通过 shmmax(单段最大字节数)和 shmall(系统总页数)限制 System V 共享内存。多个 Oracle 实例各自申请 SGA,若总和超过 shmall 可用页数,后启动的实例会在 ORA-27123: unable to attach to shared memory segment 报错中退出。
-
shmall单位是“页”,不是字节:需用getconf PAGESIZE确认页大小(通常 4KB),再把所有实例的 SGA 总和除以页大小,向上取整 -
shmmax必须 ≥ 单个实例最大 SGA(不是平均值);例如一个实例设了 12GB SGA,shmmax就不能只设 8GB - 修改后必须执行
sysctl -p生效,且重启实例才重新尝试分配
Oracle 启动时如何选择共享内存模型?
Oracle 在分配 SGA 时按固定顺序尝试三种模型:单段 → 多连续段 → 多不连续段。只要内核允许,它优先选单段(最稳定)。但若 shmmax 不足,就会退到多段模式,此时可能触发 ORA-27102: out of memory —— 错误信息指向内存,实际是共享内存参数瓶颈。
- 单段模型要求
shmmax ≥ SGA_TARGET或MEMORY_TARGET(启用 AMM 时) - 多连续段依赖
shmall足够容纳所有连续块,但内核碎片化严重时仍可能失败 - 不推荐依赖多不连续段:它绕过部分内核检查,但会增加
ksvcreate进程开销,且在 Solaris 上可能触发segspt_minfree保护机制而挂起
AMM(自动内存管理)与共享内存参数冲突吗?
启用 MEMORY_TARGET 后,Oracle 仍底层使用 System V 共享内存,只是由 MMAN 进程动态调整各池大小。此时 shmmax 必须 ≥ MEMORY_MAX_TARGET,否则实例根本无法完成初始化。
- AMM 不绕过
shmall限制:所有内存页仍计入内核统计 - 若同时设置了
SGA_TARGET和PGA_AGGREGATE_TARGET,但未设MEMORY_TARGET,则退回到 ASMM 模式,只受shmmax约束 SGA 部分 - 在 Oracle 12c+ 多租户环境中,CDB 的 SGA 包含所有 PDB 共享结构,计算总需求时容易低估
真正容易被忽略的是:shmall 是系统级硬上限,它不区分用户、进程或实例。哪怕你只跑两个实例,只要它们的 SGA 页数之和超限,第二个就起不来——错误日志里不会告诉你“是另一个实例占了”,只会静默失败。











