ORA-27123 根本原因是 kernel.shmmax 设置不足导致共享内存分配失败;需用 ipcs -lm 对比 max seg size 与 sga_max_size,调整 shmmax ≥ 单节点 SGA 并留10%余量,改后重启 systemd-sysctl、listener 和实例,并验证 ipcs -lm 输出。
oracle rac节点间进程无法通信,八成不是网络问题,而是本地共享内存分配失败——kernel.shmmax 设置不足直接导致 ora-27123,sga 根本起不来,后续所有 ipc(包括 grd 协调、lms 进程通信)全崩。
ORA-27123 报错时怎么快速确认是 shmmax 不够
看到 ORA-27123: unable to attach to shared memory segment,别急着查心跳网或防火墙:
- 先执行
ipcs -lm,看输出里max seg size是否 ≥ 当前实例的sga_max_size(单位字节); - 查
sga_max_size:连上已启动的实例(或用strings $ORACLE_HOME/dbs/spfile*.ora | grep sga_max_size); - 对比时注意单位:
ipcs -lm显示的是字节,show parameter sga_max_size默认是 bytes,但有时显示为8G,需换算成8589934592; - 若
max seg size小于 SGA 值,且cat /proc/sys/kernel/shmmax输出一致,基本锁定问题。
shmmax 值怎么算才不翻车
不能拍脑袋设成物理内存一半,尤其在多实例或 RAC 环境下:
-
shmmax必须 ≥ 单节点最大可能的sga_max_size,并留 10% 余量(比如 SGA 设 32G,shmmax至少 35G); - RAC 各节点独立申请共享内存,
shmmax按单节点算,不是集群总和; - 别设成 64GB 内存就硬配 32GB
shmmax——这会挤占其他进程(如 ASM、监听器)的共享内存空间; - 验证方法:改完后运行
sysctl kernel.shmmax,输出必须和你设的值完全一致;若不一致,说明sysctl -p没生效或被/etc/sysctl.d/下其他文件覆盖。
改完 shmmax 为什么 Oracle 还是起不来
内核参数更新 ≠ Oracle 立刻可用,中间有加载时序陷阱:
-
sysctl -p在 RHEL/CentOS 7+ 上可能被systemd-sysctl延迟加载,建议顺手执行systemctl restart systemd-sysctl; - 改完必须重新运行
ipcs -lm,确认max seg size已更新——这是 Oracle 启动前唯一可信检查点; - 别跳过重启:必须重启
listener(lsnrctl stop/start)和数据库实例(sqlplus / as sysdba→startup),否则旧的共享内存段残留,新参数不会触发重分配; - 如果用了大页(
use_large_pages=only),shmmax实际不起作用,此时要关大页或改用use_large_pages=auto配合调整vm.nr_hugepages。
shmall 容易被忽略的坑
shmall 错误不会直接报 ORA-27123,但会导致 ORA-27102: out of memory 或实例静默挂起:
-
shmall是系统级“共享内存页总数”,不是字节数,计算公式是:ceil(所有节点 SGA 总和 ÷ 4096)(x86_64 下页大小固定为 4096); - RAC 环境下,不是 “单节点 SGA ÷ 4096 × 节点数”,而是各节点 SGA 分别除 4096 后累加——因为每个节点独立调用
shmget(); - 查当前值用
cat /proc/sys/kernel/shmall,改法同shmmax,但必须同步更新/etc/sysctl.conf并sysctl -p; - 若
shmall不足,ipcs -lm中max total shared memory会明显低于理论需求,且ipcs -m可能看到大量“nattch=0”的废弃段(说明分配失败后残留)。
真正卡住人的从来不是计算公式,而是改完参数后没验证 ipcs -lm 输出、没重启 listener、没重新登录 oracle 用户(ulimit 生效依赖 shell 会话)。这些步骤漏掉任意一个,前面所有操作都白做。











