背景
公司最近上了直播业务后,数据库一直报Session连接不够,同时伴有死锁报警。当时诊断的原因就是开发逻辑有问题,死锁导致处理排队,从而引起Session堆了起来,扔给开发解决逻辑死锁的问题了。
我们的数据库环境2个节点RAC(每个节点:1500)一共3000的Session 按正常情况是满足业务需求的,但直播业务确实也是第一次接触,于是想如果开发解决了死锁问题,Session还不够怎么处理,于是就想做一次Oracle 数据库极限的Session值怎么调的测试。
最后的退路:RAC扩展节点也是一种解决方案。
- Sesssion 报警
– 独占模式:一个session对应一个process(生产环境为此模式);
– 共享模式:一个process可以服务多个session;
Tue Sep 10 13:41:35 2024
ORA-00020: maximum number of processes (1500) exceeded
ORA-20 errors will not be written to the alert log for
the next minute. Please look at trace files to see all
the ORA-20 errors
- 死锁 报警
Tue Sep 10 14:00:22 2024
Global Enqueue Services Deadlock detected. More info in file
环境版本
- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
一、Session&Process 关系
官方文档:
- 查看路径:
Getting Started=>Reference=>Part I Initialization Parameters=>Chapter 1, “Initialization Parameters”=>Changing Parameter Values in a Parameter File


查看参数值:
col name for a20
col value for a30
select NAME,VALUE from v$parameter where name in ('processes','sessions');
NAME VALUE
-------------------- ------------------------------
processes 150
sessions 264
-- 或
SQL> show parameter process ;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
processes integer 150
SQL> show parameter session;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sessions integer 264
修改:processes=500
SQL> alter system set processes=500 scope=spfile;
System altered.
-- 重启库:
SQL> shutdown immediate;
......
SQL> startup
......
#### 查看processes及sessions 值
SQL> select NAME,VALUE from v$parameter where name in ('processes','sessions');
NAME VALUE
-------------------- ------------------------------
processes 500
sessions 792
官方: session = process * 1.5+22 指导公式存疑?
- 初始化:
SQL> select 150*1.5+22 from dual;
150*1.5+22
----------
247 < 264 ?
- 调整500后:
SQL> select 500*1.5+22 from dual;
500*1.5+22
----------
772 < 792 ?
- 修改 sessions=700 结果仍然为:792
SQL> select NAME,VALUE from v$parameter where name in ('processes','sessions');
NAME VALUE
-------------------- ------------------------------
processes 500
sessions 792
SQL> alter system set sessions=700 scope=spfile;
System altered.
SQL> shutdown immediate;
......
SQL> startup
......
SQL> show parameter sessions;
NAME TYPE VALUE
------------------------------------ ----------- ---------
sessions integer 792 <--- 没有变化
- 修改 sessions=900 重启后:912
SQL> show parameter sessions;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sessions integer 792
SQL> alter system set sessions=900 scope=spfile;
System altered.
SQL> shutdown immediate;
SQL> startup
SQL> show parameter sessions;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sessions integer 912
查看历史最大值
SQL> set line 8000
SQL> select * from v$license;
SESSIONS_MAX SESSIONS_WARNING SESSIONS_CURRENT SESSIONS_HIGHWATER USERS_MAX CPU_COUNT_CURRENT CPU_CORE_COUNT_CURRENT CPU_SOCKET_COUNT_CURRENT CPU_COUNT_HIGHWATER CPU_CORE_COUNT_HIGHWATER CPU_SOCKET_COUNT_HIGHWATER
------------ ---------------- ---------------- ------------------ ---------- ----------------- ---------------------- ------------------------ ------------------- ------------------------ --------------------------
0 0 521 1447 0 24 12 2 24 12 2
ENQUEUE_RESOURCES & TRANSACTIONS 介绍
- enqueue_resources:这个参数是设置能够被锁管理器并行锁的资源的数量(11g 已弃用)
- transactions : 参数表示Oracle一个实例最多可有的事务数
SQL> show parameter ENQUEUE_RESOURCES;
SQL> show parameter TRANSACTIONS ;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
transactions integer 871
transactions_per_rollback_segment integer 5
-- transactions = 1.1*sessions
SQL> select 792*1.1 from dual;
792*1.1
----------
871.2
二、Session&kernel.sem的参数关系
kernel.sem 查看及介绍
- Oracle服务进程需要使用信号量通讯,1个server进程最少一个信号量
[root@db ~]# vim /etc/sysctl.conf
kernel.sem = 250 32000 100 128
[root@db ~]# cat /proc/sys/kernel/sem
250 32000 100 128
- kernel.sem=semmsl semmns semopm semmni
#semmsl:表示一个信号量集合中能够包含的信号量最大数目。
#semmns:表示系统内可允许的信号量最大数目。
#semopm:表示单个semopm()调用在一个信号量集合上可以执行的操作数量。
#semmni:表示系统信号量集合总数。
- 查看当前信号量设置
[root@db ~]# 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 <== 信号量最大值
- 查看当前信号量使用
[root@db ~]# ipcs -su ------ Semaphore Status -------- used arrays = 20 <== 已使用数组 allocated semaphores = 3179 <== 已分配信号量数
- 其它查看命令
[root@db ~]# ipcs -h ipcs provides information on ipc facilities for which you have read access. Resource Specification: -m : shared_mem <== 查看系统共享内存信息 -q : messages <== 查看系统消息队列信息 -s : semaphores <== 查看系统信号信息 -a : all (default)<== 查看共享内存、消息队列及信号量所有信息 Output Format: -t : time <== 查看最新调用IPC资源的详细时间 -p : pid <== 查看共享内存、消息队列相关进程之间的消息 -c : creator <== 查看IPC的创建者和所有者 -l : limits <== 查看限制 -u : summary <== 查看使用情况 -i id [-s -q -m] : details on resource identified by id usage : ipcs -asmq -tclup ipcs [-s -m -q] -i id ipcs -h for help.
三、Session与 limits.conf
- limits.conf
[root@db ~]# cat /etc/security/limits.conf
oracle soft nproc 2047 <== 单个用户可用的最大进程数(超过警告)
oracle hard nproc 16384 <== 单个用户可用的最大进程数(超过报错)
oracle soft nofile 1024 <== 可以打开的文件描述符的最大数(超过警告)
oracle hard nofile 65536 <== 可以打开的文件描述符的最大数 (超过报错)
# 注:如果没有设置,默认值为:1024
小结
以目前查到的资料Session与Process、kernel.sem、limits.conf三个方向相关。
- 其中官方的指导公式:session = process * 1.5+22 目前存疑(可能是我理解的不透彻,希望大家指正)。单独调整Session参数,低于公式(指导公式)的值保持不变,高于公式的值生效。
- kernel.sem 此参数的调整需要谨慎,来自网上的案例“OS内核参数(Sem)在高负载的Oracle数据库中如何设置”的结论是参考官方参数即可。此方向需要进行后续测试验证。
- limits.conf 对进程数与打开文件数的限制同步需要后续测试。
欢迎赞赏支持或留言指正

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




