问题描述:
服务器上有3个实例,之前processes都是500,按照业务要求,将processes均修改为2000,依次启动实例,发现最后一个实例无法启动,报错:
Errors in file/u01/app/oracle/diag/rdbms/scb/scb1/trace/scb1_1899600.trc:
ORA-27152: attempt topost process failed
ORA-27300: OS system dependentoperation:semop failed with status: 28
ORA-27301: OS failure message: No spaceleft on device
ORA-27302: failureoccurred at: sskgpwvp2
问题分析:从日志中很容易看出是由于资源问题导致,又因为刚才只修改了processes,因此断定与processes数量有关。经过分析,确认是超过系统设置的信号集导致。
解决办法:将信号量调大
vi /etc/sysctl.conf
#kernel.sem = semmsl semmns semopm semmni
kernel.sem = 250 50000 100 200
sysctl -p
信号量semaphore
Semaphore allocation(From meatlink [ID 15566.1]) Semaphore allocation
is much simpler than shared memory. Oracle just needs to allocate a
number of semaphores equal to the processes parameter in “init.ora”.
PROCESSES will be used to refer to this value. Note on machines with a
post-wait kernel extension, Oracle does not need to allocate
semaphores (because it doesn’t need to implement its own post-wait
mechanism).Oracle uses semaphores to control concurrency between all the
background processes (pmon, smon, dbwr, lgwr, and oracle shadows).
Semaphores are also used to control two-task communication between the
user process and shadow process if the fast (shared memory) driver is
used. And in the Unix ports based on MIPS RISC processors, Oracle uses
a special semaphore to perform basic test & set functions that are not
provided by the processor
信号量,有时候也被称为信号灯,是一个非负整数计数器。通常用来协调对资源的访问。信号量用于提供进程间的同步或者一个进程内的多个线程来共享资源,比如共享内存。其中信号计数会初始化为可用资源的数目。当线程在资源增加时会增加计数,在删除资源时会减小计数,这些操作都以原子方式执行。如果信号计数变为零,则表明已无可用资源。计数为零时,尝试减小信号的线程会被阻塞,直到计数大于零为止。
信号量的数量可以通过系统内核参数SEMMSL来设置。
a、参数SEMMSL
该参数定义了每个信号集的最大信号数量
Oracle 建议将 SEMMSL 设置为Oracle参数文件(用于Linux系统中的所有数据库)中的最大PROCESS实例参数的设置值再加上10 。
此外, Oracle建议将 SEMMSL 的值设置为不少于100。
b、参数SEMMNS
该参数控制整个 Linux 系统中信号(而不是信号集)的最大数。
Oracle 建议将 SEMMNS 设置为:
系统中所有数据库实例的PROCESSES参数设置值的总和,加上最大PROCESSES值的两倍,最后根据系统中Oracle数据库的数量,每个加10
使用计算式来确定在 Linux 系统中可以分配的信号的最大数量。取两者中较小的一个值:SEMMNS 或(SEMMSL * SEMMNI)
在Oracle 10g和Oracle 11g中,该值被建议设置为SEMMSL * SEMMNI (250*128=32000)
c、参数SEMOPM
SEMOPM: 该内核参数用于控制一次semop系统调用可以执行的信号操作的数量semopm。semop 系统调用(函数)提供了利用一个 semop
系统调用完成多项信号操作的功能。一个信号集能够拥有每个信号集中最大数量的SEMMSL 信号,因此建议设置 SEMOPM 等于SEMMSL 。
Oracle 建议将 SEMOPM 的值设置为不少于 100
d、参数SEMMNI
该参数定义整个Linux系统中信号集的最大数量。Oracle 建议将 SEMMNI 的值设置为至少为128 。
e、查看当前的信号量设置
cat /proc/sys/kernel/sem
250 32000 32 128
##(这几个值分别是:SEMMSL, SEMMNS, SEMOPM, and SEMMNI)
简要描述这四个参数
SEMMSL: 每个信号集的最大信号数量
SEMMNS: 系统信号量(非信号集)最大数量
SEMOPM: 每次semop系统调用可执行的信号操作数
SEMMNI:系统信号量集最大数量
也可以通过ipcs -ls来查看当前的信号量设置
ipcs -ls
f、信号量设置示例
SEMMSL应该设置为服务器中实例中具有最大的PROCESSES参数+10,例如,当最大的PROCESSES参数为2000时,SEMMSL应设置为2010。
SEMMNS参数应设置为SEMMSL*SEMMNI,接上例SEMMSL为2010,SEMMNI的值一般为128,则SEMMNS参数应为(2010*128)=257280。
SEMOPM参数应设置与SEMMSL参数相同,接上例此处应设置为2010
因此对于信号量建议做如下设置
sysctl -w kernel.sem=”2010 257280 2010 128″