ORA-27300 报 fork failed 或 semget failed 的本质是操作系统 IPC 资源不足,而非磁盘空间问题;核心在于信号量耗尽、ulimit -u 过低或内核参数限制,需结合 ipcs、ulimit、dmesg 交叉验证。
ORA-27300 报 fork failed 或 semget failed,本质不是磁盘空间问题
看到 ora-27301: os failure message: not enough space 或 no space left on device,第一反应查磁盘?错。这类报错在 rac 节点启动阶段(startup nomount)就出现,根本还没读数据文件,df -h 再空也白搭。真正卡住的是操作系统 ipc 资源——尤其是信号量(semaphore)或进程/线程创建能力(fork)。rac 双节点环境下,一个节点能启、另一个启不动,大概率是该节点的内核信号量池被旧实例残留占满,或 ulimit -u(max user processes)被设得太低。
快速定位信号量是否耗尽:用 ipcs + 计算公式验证
登录报错节点,执行:ipcs -s | wc -l 查当前信号量集总数;ipcs -ls 看系统上限:max semaphores system wide 和 max number of arrays。
关键要核对:Oracle 启动所需信号量 ≈ (PROCESSES + 10) × 实例数(注意不是所有实例共享同一套,而是每个实例独立申请)。比如两个实例,PROCESSES=800,理论需 (800+10)×2 = 1620 个信号量;但若 ipcs -ls 显示 max semaphores system wide = 1280,就必然失败。
- 别只看
/proc/sys/kernel/sem的四个数值,更要结合ipcs -s输出中每个信号集的nsems值累加——残留的未清理信号集(尤其 owner 是root或已删用户)会悄悄吃掉配额 - RAC 中 OCR/Voting Disk 访问异常(如
PROC-26)有时会触发信号量泄漏,此时crsctl stop crs -f后再ipcs -s -r清理比硬重启更稳妥 - Oracle 19c+ 默认启用
_use_ism,若关闭它(alter system set "_use_ism"=false),可能意外增加信号量需求,排查时需确认该隐含参数状态
ulimit 和 /etc/security/limits.conf 配置必须匹配 RAC 实际负载
RAC 节点间资源限制不一致是高频雷区。比如节点一设了 oracle soft nproc 16384,节点二还是默认的 4096,启动第二个实例时就会在 skgpspawn3 失败并报 status=12(ENOMEM)。重点检查三项:
-
ulimit -u(max user processes):必须 ≥PROCESSES × 1.2(留出后台进程余量),且软限 ≤ 软限 -
ulimit -n(open files):RAC 心跳、ASM 连接、监听器全靠它,建议 ≥ 65536 -
ulimit -l(locked memory):若启用大页(use_large_pages=only),此项必须设为unlimited,否则sskgpcreates直接失败
改完 /etc/security/limits.conf 后,务必重新以 oracle 用户登录终端生效(su - oracle),仅改配置不重登无效。
不要跳过 dmesg 和 /var/log/messages 的时间戳线索
RAC 节点“看似正常”但无法启动实例,常因内核级资源争抢被掩盖。运行 dmesg -T | tail -50,重点搜 Out of memory、fork: Cannot allocate memory 或 semop: too many semaphores。曾有案例显示:AIX 上 max_client% 设为 90 导致 filesystem cache 占满物理内存,fork 时实际已无页框可用,错误却显示为 Not enough space ——这种跨层误导,只有 dmesg 的时间戳和错误上下文才能锁定。
信号量不是孤立参数,它和共享内存段(shmmax)、进程数、甚至 SELinux 的 allow_domain_fd_use 策略都可能耦合。一次清理没效果,就说明至少有两个资源同时触顶,得按 ipcs → ulimit → dmesg → sysctl -a | grep sem 顺序交叉验证,少看一步,就得多重启一次。










