现象
我们在一个客户上进行恢复完成后,在RAC的第二个节点,Oracle实例启动失败,有下面的提示信息:
ORA-27154: post/wait create failed ORA-27300: OS system dependent operation:semget failed with status: 28 ORA-27301: OS failure message: No space left on device ORA-27302: failure occured at: sskgpcreates
原因分析
在metalink上查到(Doc ID 314179.1),符合这个错误,里面提到产生的原因是:
SEMMNS is set to 230 against 1024(Minimum Recommended). The low value of SEMMNS is preventing to start the instance. The SEMMNS parameter should be set to the sum of the PROCESSES parameter for each Oracle database, adding the largest one twice, and then adding an additional 10 for each database. SEMMSL is set to 60 against 256 (Minimum Recommended).
到生产机上检查:
[oracle@localhost ~]$ sudo cat /proc/sys/kernel/sem 250 32000 100 128 [root@localhost ~]# ipcs -ls ------ Semaphore Limits -------- max number of arrays = 128 max semaphores per array = 250 max semaphores system wide = 32000 max ops per semop call = 100 semaphore max value = 32767
250 SEMMSL max semaphores per array 表示每个信号集中的最大信号量数目 最小250;对于processes参数设置较大的系统建议设置为processes+10
32000 SEMMNS max semaphores system wide 表示系统范围内的最大信号量总数目,=SEMMSL * SEMMNI
100 SEMOPM max ops per semop call 调用单个信号集中最大信号数量至少100,或者等于SEMMSL
128 SEMMNI max number of arrays 信号集的最大值,最少128
从检查结果来看并没有问题,问题却是:理论上支持32000个信号量是 SEMMSL(250)*SEMMNI(128)=SEMMNS(32000),但实际用ipcs命令检查:一个信号的identifiers 包含最多156个信号量,
$ ipcs ... ------ Semaphore Arrays -------- key semid owner perms nsems 0x450e15bd 0 root 666 1 0x0000cace 32769 root 666 1 0x358b172c 327683 oracle 660 104 0x9053d038 11075588 oracle 660 156 0x9053d039 11108357 oracle 660 156 0x9053d03a 11141126 oracle 660 156 0x9053d03b 11173895 oracle 660 156 ...
在没有启动一个新的实例的时候,这里包含了大约1000个信号的identifier,其中nsems对应信号量集中信号量的个数,那么156 x 128 = 19968,并不是32000。
参考文档:Database Startup Fails with ORA-27300: OS system dependent operation:semget failed with status: 28 (Doc ID 949468.1)
在系统日志: /var/log/message 里面应该有类似下面的提示,但当时没有查。
Jun 24 11:36:59 localhost Server Administrator (Shared Library): 14691 0 - Data Engine A semaphore set has to be created but the system limit for the maximum number of semaphore sets has been exceeded
解决方案
增加SEMMNI,可以扩容信号量。
查询当前内核里面的信号量, # /sbin/sysctl -a | grep sem
修改 SEMMNI ,编辑/etc/sysctl.conf,将 kernel.sem = 250 32000 100 128改成 kernel.sem = 250 32000 100 300
生效: # /sbin/sysctl -p
教训是当一台机器上有多个实例的时候,也有可能只有一个实例,但grid用户也会占用部分信号量,所以不能照搬标准设置。
这是改完的/etc/sysctl.conf