oracle无法启动ORA-27154,ORA-27300,ORA-27301,ORA-27302

发现一台实例突然无法启动,版本11.2.0.4

1
2
3
4
5
SQL> startup nomount
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 occurred at: sskgpcreates

看报错信息大概是sskgpcreates创建失败,资源不足。这个主要是在数据库启动时根据process参数设置的值去分配信号资源,如果内核参数设置的不合理,则会导致报错。

在Linux里,信号量主要是用来控制特定进程的利用率。它是一个可共享的资源,分别由P (wait)和V (signal)函数操作,这两个函数分别递减和递增信号量。当进程需要资源时,发出”wait”,信号量递减。当信号量的值为0时,资源不可用,调用进程会spin或阻塞(视情况而定),直到资源可用为止。当进程释放由信号量控制的资源时,它会增加信号量并通知等待的进程。由下面几个参数控制

信号量 描述 最小值
SEMMSL 每个组的最大信号量 128
SEMMNS 系统级别最大信号数
SEMOPM 每个semop调用的最大操作
SEMMNI 最大组数

计算当前最少需要的信号量总数

1
sum(本机所有实例的process参数值)+本机系统需求+本机其他程序需求
  • 设置semmns大于这个sum值
  • 设置semmsl为256
  • 设置semmni为semmns/semmsl

查看当前系统参数

1
2
3
4
5
6
7
8
$ ipcs -ls

------ Semaphore Limits --------
max number of arrays = 128 // SEMMNI
max semaphores per array = 250 // SEMMSL
max semaphores system wide = 32000 // SEMMNS
max ops per semop call = 100 // SEMOP
semaphore max value = 32767

从这个配置来看理论上系统级别的最大信号数为32000,最大组数为128,每个组最大信号量250。

但是ipcs命令显示每个信号量标识符最多可以容纳156个Oracle信号量

1
2
3
4
5
6
7
8
9
10
11
$ ipcs
...
------ Semaphore Arrays --------
key semid owner perms nsems
0x2ff4a110 5701651 oracle 640 156
0x2ff4a111 5734420 oracle 640 156
0x2ff4a112 5767189 oracle 640 156
0x2ff4a113 5799958 oracle 640 156
0x2ff4a114 5832727 oracle 640 156
0x2ff4a115 5865496 oracle 640 156
...

那么实际上最大可用的信号总量为156 x 128=19968,所以要增加最大可用组数。

1
2
3
4
5
[root@whzdb1 ~]# /sbin/sysctl -a | grep sem
kernel.sem = 250 32000 100 128

-- change to:
kernel.sem = 250 32000 100 200