技术申请
上周收到XZH转过来的一封CD渠道高级技术申请,反映SN医院的数据库经常提示ora-12518(TNS:listener could not hand off client connection)错误,以往出现这个错误,往往是由于数据库是32位,内存分配限制所致,再出现这个错误后,渠道已经对数据库进行了升级,内存参数进行了调整,且把数据库参数SESSION调整为 800,远远高于医院的用户站点数,但仍然还是无法避免该错误的出现,因此申请高级技术支持,希望能解决该问题。
问题现象
首先我们应该看下当年连接的用户数量,通过plsql dev工具的会话查看,部分截图如下:
从上面的结果我们可以看出几点问题,首先当前数据库的连接数确实比较多,与医院实际站点用户数不符,另外同一用户都多个连接,且大部分连接的状态是‘INACTIVE’及为非活动会话,肯定是不正常的,因此处理这些非活动会话是解决这个问题的关键。
问题分析
首先需要明确这个问题产生的原因,系统中出现大量inactive会话,无外乎有2种可能:
1.应用程序连接方式的导致,程序在退出应用后,连接没有释放;
2.网络原因,导致程序异常退出,会话资源没有释放;
应用程序上除了医保是渠道自己编写可能造成原因外,HIS程序由于是公司提供,既然也出现这个inactive会话,那就应该从网络原因着手排查,而网络建议多从网络带宽,交换机,防火墙设置着手,首先建议技术人员查下网络带宽是否正常。
1.带宽检查:ping大包是否有掉包现象
2.检查防火墙或者IPS等类似设备的设置,是否设置有timeout限制,必要时是可以暂停防火墙一段时间观察。
3.交换机检查,这个建议咨询下交换机工程师。
4.数据库方面,可以通过设置SQLNET.EXPIRE_TIME=X(分钟)来启动Dead Connection Detection(DCD 僵死进程检测)释放资源。
5.另外对用户可以使用资源管理,设置概要文件中的idle_time参数来限制空闲会话存在的时间。
因此,由于该问题的出现原因比较复杂,涉及第三方网络,多管齐下是解决这个问题的主要思路,一边叫技术人员现场检查网络,一边数据库这边做一些设置。
解决过程
通过上面的分析,数据库这边需要做上面4,5两个操作。
一、启动DCD 僵死进程检测
方法很简单,就是在sqlnet.ora文件中添加SQLNET.EXPIRE_TIME参数,这样Oracle会在指定的空闲间隔时间内,发送一个10个字节的探测包,如果客户端进程无响应则会启用PMON后台进程对这个进程的所占用的相关资源进程清理操作,包括内存资源(如PGA,UGA)、变量、锁等进行释放,操作方法如下:
1.在sqlnet.ora文件中添加这个参数:
SQLNET.EXPIRE_TIME= <# of minutes>
2.重启监听。
这样,DCD僵死进程检查就已经启动了,接着用资源管理,限制空闲会话存在的时间。
二、启用资源管理
1.修改数据库参数resource_limit值为true,命令如下:
sql>alter system set resource_limit=true scope=spfile;
2.重启下数据库
3.修改默认用户概要文件的idle_time参数
sql>alter profile default limit idle_time 60;
注*:如果不想对某些用户进行限制(如收费人员由于涉及到夜班,可能空闲时间比较长是正常情况),可以单独建个不受限制的概要文件,把这类人员的profile指定为你建的概要文件。
通过上面的设置,就保证空闲会话只能在数据库中保留60分钟,接着就需要用户实际观察启用效果。
第二天,用户反馈结果,说还是存在大量会话,不过会话的状态已经由’INACTIVE’变为了’SNIPED’,如下图:
Sniped状态是由idle_time资源管理规则导致终止的会话连接状态,不过服务器上进程同样不会立即清除,需要在服务器上用操作系统命令删除进程,手工释放资源,我们可以考虑做个批处理,定时执行一次,清除下这种状态的会话,方法如下:
1. C盘先建立一个bat文件,如(kill进程.bat) ,内容如下:
Set ORACLE_SID=orcl
sqlplus system/his @C:/kill_session.sql
c:/kill_session.bat
2. C:/kill_session.sql内容如下:
spool c:/kill_session.bat
set head off
set feedback off
set pagesize 1000
set term off
COLUMN EVENT FORMAT A30
Select 'orakill orcl ' || p.spid || '' From v$process p, v$session s Where p.addr = s.paddr and status ='SNIPED' and s.username is not null;
spool of
exit
注*:上面的实例名是orcl,如果不是请修改红色部分,system密码根据具体情况进行修改
通过在服务器上执行上面的批处理操作,该状态的会话被彻底清楚,资源得到释放,本例中由于无法对网络进行调整,目前只能通过这种方式也算间接的处理了该问题。
总结
通过本例应该了解oracle数据库的几点知识:
1. 用户会话的几种状态的含义,active表示活动会话,inactive表示空闲会话,sniped表示idle_time资源限制终止的会话
2. 通过资源管理的方式对用户的一些资源进行限制(本例中限制的是空闲会话连接时间)。
3. 如何彻底的释放连接资源,手工删除oracle连接进程。