原来是它(Oracle.ManagedDataAccess.Client)再说ORA-12516故障解决
最近ORA-12516错误频出,我也是不胜其烦。但是每次都找不到根本原因,只能停监听、杀进程或者直接关闭客户端程序。复述一下故障现
最近一直和ORA-12516报错作斗争。接着我之前分享的一篇文章说起 ,当时通过kill进程的方法临时解决了问题,但是根本问题没有找到——为什么设备会产生大量连接?说到底,这个问题当时并没有解决,并且继续“折磨”了我将近一个月。这段时间,,不断地有人找我——数据库连不上了!!!问题到底出在哪儿了呢。
下面和大家分享一下解决过程,希望对大家有所借鉴。
开发环境
操作系统:Windows Server 2008 R2 Standard
数据库:Oracle 10g(10.2.0.4) 64bit
频繁报错ORA-12516,初步分析
最近ORA-12516错误频出,我也是不胜其烦。但是每次都找不到根本原因,只能停监听、杀进程或者直接关闭客户端程序。
复述一下故障现象:连接数据库报错,提示“ORA-12516”错误——“ORA-12516: TNS: 监听程序无法找到匹配协议栈的可用句柄”。
一直很稳定的系统架构,为什么突然不行了呢?
数据库processes参数使用的默认值150,相应的sessions为170,;
我们采用C/S架构,其中Client数量并不多,也就20台左右,所以正常情况下sessions数量为40左右,其中包括16个数据库内部连接。
可现在,sessions数量动辄就到了130~140,直接导致ORA-12516报错。
下面贴一个当时的查询结果:
SQL> set pagesize 150
SQL> set linesize 200
SQL> col username for a10
SQL> col terminal for a20
SQL> col program for a20
SQL> select username,program,terminal,count(*) from v$session group by rollup(username,program,terminal);
USERNAME PROGRAM TERMINAL COUNT(*)
---------- -------------------- -------------------- ----------
......此处省略内容
ORACLE.EXE (q000) 1
ORACLE.EXE (q001) DBSERVER 1
ORACLE.EXE (q001) 1
16
SYS sqlplus.exe DBSERVER 1
SYS sqlplus.exe 1
SYS 1
HOEGH HOEGH.exe Client7 1
HOEGH HOEGH.exe CLIENT2 95
HOEGH HOEGH.exe Client3 1
HOEGH HOEGH.exe Client4 2
HOEGH HOEGH.exe CLIENT5 28
HOEGH HOEGH.exe Client6 1
HOEGH HOEGH.exe 128
HOEGH 128
145
可以看出,CLIENT2 和CLIENT5 两个终端的连接数分别为95和28,肯定有问题。
查询session,尝试定位故障设备
通过select username,program,terminal from v$sessions;查询数据库连接,看到某一台或者某两台的session数达到30,有的甚至超过70。把相应设备的应用程序(应用程序连接数据库)重启后,问题有时能迅速缓解,有时却没有效果。
起初是怀疑Client设备的硬件或者操作系统,因为这些设备中的操作系统比较杂(实验室为了测试方便),包括32位的Windows XP、32位及64位的Win7,还有64位的Win8。
后来经过长时间的观察,发现故障设备并不固定,也就是说,每一台设备都有可能成为“故障设备”。
有点迷茫了。
C#清空连接池
经过长时间观察及初步分析,得出的结论是这个问题可能与具体设备没有直接关系,而是和目前的数据库断连判断代码有关。
我们的应用程序为了显示数据库连接状态,定时去连接数据库,起到“心跳”的作用。我们怀疑是不是每台设备都这么去频繁连接数据库,而这些连接却没有释放,时间长了session数量就上去了,于是在代码中添加了清空连接池的语句。
但是,没有效果。
其实,现在是怀疑一切了,因为以往项目我们采取的是同样的数据库“心跳”机制,一直没有出过问题。
添加静态监听
后来一直在网上查这个ORA-12516,不少朋友提到了通过监听去发现、解决问题。我看了一下数据库服务器的监听日志Listener.log,好家伙,都80多M了,记事本都打不开了。最后用UE打开监听日志,发现里面大片的TNS-12514报错。
10-6月 -2015 16:26:53 * service_update * hoegh * 0
10-6月 -2015 16:26:56 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=))(SERVICE_NAME=hoegh)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.3.191)(PORT=50641)) * establish * hoegh * 12514
TNS-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
10-6月 -2015 16:26:58 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=))(SERVICE_NAME=hoegh)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.3.191)(PORT=50644)) * establish * hoegh * 12514
TNS-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
10-6月 -2015 16:26:58 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=))(SERVICE_NAME=hoegh)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.3.191)(PORT=50645)) * establish * hoegh * 12514
TNS-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
10-6月 -2015 16:26:58 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=))(SERVICE_NAME=hoegh)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.3.191)(PORT=50647)) * establish * hoegh * 12514
TNS-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
10-6月 -2015 16:26:58 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=))(SERVICE_NAME=hoegh)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.3.191)(PORT=50648)) * establish * hoegh * 12514
TNS-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
10-6月 -2015 16:27:08 * service_update * hoegh * 0