shmmax必须≥单实例最大sga(如12gb),否则oracle启动时因无法分配连续共享内存段而报ora-27123或ora-27102;多实例下取各实例sga最大值而非总和,且修改后须执行sysctl -p生效。

因为 Oracle 启动 SGA 必须申请一块连续共享内存段,而 shmmax 限制了单段最大字节数;若它小于你配置的 SGA_TARGET 或 MEMORY_MAX_TARGET,实例根本无法完成初始化,直接报 ORA-27123 或 ORA-27102。
shmmax 不够时的典型错误现象
安装或启动阶段卡在“Initializing Oracle instance…”后退出,日志里明确出现:
ORA-27123: unable to attach to shared memory segment-
ORA-27102: out of memory(注意:这不是物理内存不足,是共享内存段分配失败) - 静默安装时
runInstaller进程秒退,installActions.log中无堆栈,只有 JVM 启动成功但 Oracle 进程未起来
怎么算出该设多大?别拍脑袋
关键不是“物理内存一半”,而是必须 ≥ 单个实例的最大 SGA 需求。例如:
- 你计划给一个实例配
SGA_TARGET=12G→shmmax至少设为12884901888(12 × 1024³) - 若启用了
MEMORY_TARGET=16G→shmmax必须 ≥17179869184(16 × 1024³) - 多实例环境,取其中最大的那个 SGA 值,不是总和——
shmmax管的是“单段”,不是“总和”
为什么改了 /etc/sysctl.conf 还不生效?
常见操作断点:
- 只改了文件,没执行
sysctl -p—— 参数压根没加载进内核 - 执行了
sysctl -p但返回警告,比如error: "kernel.shmmax" is an unknown key,说明拼写错误或内核版本太旧不支持该参数名 - 用
echo 12884901888 > /proc/sys/kernel/shmmax临时改过,但重启后失效,而你忘了永久配置 - 在容器或云主机上,/etc/sysctl.conf 被覆盖或 systemd-tmpfiles 干预了加载顺序
/dev/shm 和 shmmax 是一回事吗?
完全不是。这是最容易混淆的两点:
-
shmmax是内核对 System V 共享内存段的单段大小限制(字节),影响 SGA 分配 -
/dev/shm是 tmpfs 挂载点,只影响启用MEMORY_TARGET时的自动内存管理元数据存储;它报错是ORA-00845,和shmmax报的ORA-27123是两条独立路径 - 两者都得调,但不能互相替代:
shmmax不够,连 ASMM 模式都起不来;/dev/shm不够,只在 AMM 模式下挂
真正容易被忽略的是:Oracle 在分配 SGA 时会优先尝试单段模式,一旦 shmmax 不足,它不会提示“请调大 shmmax”,而是默默退到多段模式——而多段模式在某些内核或碎片化严重时,又会触发其他不可见的失败。所以不要等报错才调,要在规划 SGA 时就同步算好并固化到 /etc/sysctl.conf。











