shmmax需≥SGA最大值(如sga_max_size)并留10%余量,shmall需≥所有实例SGA总和÷4096;RAC环境还需额外考虑GRD开销且各节点独立计算;修改后须sysctl -p生效、验证ipcs -lm、重启listener与数据库。
shmmax 设置多少才够用?
oracle 实例启动时若报 ora-27123: unable to attach to shared memory segment,八成是 shmmax 太小——它限制单个共享内存段最大字节数,必须 ≥ oracle sga 最大可能值(比如 sga_max_size 配置值)。
- 查当前值:
cat /proc/sys/kernel/shmmax - Oracle 推荐下限:取
sga_max_size(单位字节)向上取整到 4KB 边界,但实际建议留 10% 余量 - 别盲目设成物理内存一半——64GB 内存设 32GB
shmmax可能导致其他进程共享内存失败 - 常见错误:把
shmmax设成 4G(即4294967296),但 Oracle 实际需要 4.2G,仍会报错
shmall 怎么算才不溢出?
shmall 是系统级总共享内存页数上限(单位:页,通常一页 = 4KB),它不是按 Oracle 单实例算的,而是所有共享内存段加起来不能超这个页数。
- 公式:
shmall ≥ (所有 Oracle 实例的 SGA 总和 + 其他应用共享内存) ÷ 4096 - 查当前页大小:
getconf PAGESIZE(绝大多数是 4096) - 漏算点:RAC 环境中每个节点都要算;如果启用了 AMM(
memory_target),也要计入,因为 AMM 底层仍走 shm - 典型坑:只按一个实例算
shmall,上线第二个实例后ipcs -lm显示shmmax没超,但shmall已满,新实例起不来
修改后 Oracle 不生效?检查这三处
改完 /etc/sysctl.conf 并执行 sysctl -p,不代表 Oracle 就能立刻用上新值——内核参数加载时机和 Oracle 启动顺序有依赖关系。
- 确认是否真正生效:
sysctl kernel.shmmax和sysctl kernel.shmall输出值必须匹配你写的配置 - Oracle 启动前必须确保
ipcs -lm输出的max seg size和max total shared memory已更新,否则说明内核没重载 - RHEL/CentOS 7+ 使用 systemd 的机器,
sysctl -p有时被systemd-sysctl延迟加载,建议重启systemd-sysctl服务或直接 reboot 验证 - 别跳过重启 Oracle listener 和数据库:改完内核参数后,
sqlplus / as sysdba连上去执行startup才真正触发共享内存分配
为什么 RAC 环境更容易踩坑?
RAC 不是简单地把单实例复制多份,它的共享内存模型更复杂:除了各节点自己的 SGA,还有全局资源目录(GRD)、锁管理器(LMON)等跨节点通信结构,都吃同一套 shmmax/shmall。
- RAC 中每个节点的
shmmax必须 ≥ 本节点 SGA + GRD 预估开销(一般加 512MB 安全余量) -
shmall要算全集群所有节点的共享内存总和,不是单节点乘节点数——因为每节点独立申请,互不共享页表 - 容易忽略的兼容性点:Oracle 11.2.0.4 之前版本在某些内核(如 3.10+)上对大
shmall值支持不稳定,升级前务必验证 - 验证命令别只跑
ipcs -lm,要跑ipcs -m | wc -l看当前已分配段数,再对比shmall是否真够用

















