shmmax是单个共享内存段最大字节数,shmall是系统总共享内存页数;二者必须匹配物理内存与应用需求,如oracle要求shmmax≥sga且shmall≥ceil(shmmax/页面大小),否则报ora-27123或启动失败。

Linux 中修改最大共享内存不是“改个配置就完事”,关键在 shmmax 和 shmall 两个参数是否匹配物理内存与应用场景——尤其对 Oracle、PostgreSQL、MPI 等依赖大段连续共享内存的程序,设小了直接报 ORA-27123 或启动失败。
查当前值:别猜,先看 /proc/sys/kernel/shmmax 和 /proc/sys/kernel/shmall
这两个文件直接反映内核当前生效的限制:
-
shmmax是单个共享内存段最大字节数(比如 Oracle SGA 必须装进一个段,不能拆) -
shmall是系统允许的总共享内存页数(单位是页,不是字节),必须 ≥ceil(shmmax / getconf PAGESIZE) - 运行
getconf PAGESIZE查页面大小(多数 x86_64 是 4096) - 例如:若
shmmax=1073741824(1GB),页面为 4096,则shmall至少要 ≥ 262144
临时调大:用 sysctl -w 或直接写 /proc,适合验证和调试
不需要重启,改完立刻生效,但重启后丢失:
- 设
shmmax为 2GB:sudo sysctl -w kernel.shmmax=2147483648 - 设
shmall为 524288 页(对应 2GB):sudo sysctl -w kernel.shmall=524288 - 或绕过
sysctl直接写:echo 2147483648 | sudo tee /proc/sys/kernel/shmmax - 注意:写
/proc要 root 权限;sysctl -w更安全,会做基础校验
永久生效:必须写进 /etc/sysctl.conf,且运行 sysctl -p
/etc/rc.local 方式已不推荐(systemd 下可能不执行),标准做法是:
- 编辑
/etc/sysctl.conf,追加两行:kernel.shmmax = 2147483648kernel.shmall = 524288 - 保存后立即加载:
sudo sysctl -p(不重启也生效) - 验证是否载入:
sysctl kernel.shmmax kernel.shmall - 错误点:只改了 conf 文件但没运行
sysctl -p,或拼错参数名(如写成shm_max)会导致静默失败
为什么设太大反而出问题?物理内存和页面对齐才是硬约束
常见误区是“越大越好”,但实际有三重限制:
-
shmmax不应超过物理内存一半(官方建议),否则可能挤占其他进程可用内存 -
shmall值过大但物理内存不足时,shmget可能成功,但首次shmat时触发 OOM killer - 某些老内核(如 2.6.32)对
shmmax有隐式上限(如 4GB),设更高会被截断,需用cat /proc/sys/kernel/shmmax确认最终值 - Oracle 等应用常要求
shmmax ≥ SGA_TARGET,但还要预留至少 10% 内存给系统缓存和页表
真正卡住人的地方,往往不是不会改,而是改完没验证是否被内核真正接受,或者忽略了 shmall 与页面大小的换算关系——shmmax 设对了,shmall 没跟上,照样分段失败。











