oracle 报12560,UNIX系统中Oracle报TNS-12560错误的解决思路

本文档记录了一次排查AIX系统上应用程序出现ORA-12560错误的过程。问题源于应用程序打开的文件描述符超过系统限制,导致数据库连接失败。通过分析进程资源限制、使用procfiles工具及检查代码,发现是由于未正确关闭FIFO管道文件句柄导致。修复代码并优化资源管理后,问题得到解决。
摘要由CSDN通过智能技术生成

前几天接到客户的一个电话,需要到现场解决一个问题。客户的电话就是命令,于是放下手中的活,急忙赶往客户现场。到达客户现场后,客户反应本地的一个应用程序隔一段时间就报错,同时客户传来了一张报错的图片,如下所示:

c983a46d863cea7860d1ccdef30f414c.png

从上图来看,客户端的应用程序报错信息是ORA-12560或者TNS-12560错误,通过oerr命令

65480e70f085cdea6662b44c69b8bf05.png

得知该错误是协议适配器错误,既然是网络相关的错误,就建议客户收集了数据库的监听器日志、sqlnet.log文件以及数据库的alert日志文件,然后依次查看这些文件,都没有发现有用的线索。此时陷入了僵局。

客户反映该应用程序不通过tns访问数据库,是在数据库服务器上直接跑的,这样来说这个应用程序是通过beq访问的数据库。也就是应用程序不走网络监听访问数据库,而是通过进程间通信访问数据库,这样性能更高。

日志中没有线索,就到Oracle Support网站上查吧,查了半天,发现12560错误相关的问题都是发生在Windows平台上的,只有一两篇与UNIX环境有关,其中一篇   Creating Inside An Linux/Unix Process Huge Number (500 and higher)Of Connections Against Database Fails With Network Errors ORA-12157 OrORA-12560 (文档 ID 563237.1)介绍的是FD_FILESIZE限制了进程打开的文件描述符,在AIX平台下的限制是65536,解决该问题需要安装补丁,因临近假期,这个核心业务系统的数据库打补丁也不现实,只好作罢,此时又限入了僵局,头疼啊。

该如何解决这个问题呢,后来突然一想,如果真的是这个BUG导致的问题,那么这套系统运行了三年了,早该出问题了,这个报错应该不是这个问题引起的。看来这个文档所描述的问题可能和我们遇到的有所不同,不过既然文档中提到了资源限制的问题,也给了我们一些思路,那就先查一查应用程序属主的资源限制吧,检查结果如下

092297775ffa41c3269056e6eea59b10.png

看到上面的输出似乎有点感觉了,一个小应用程序32MB内存应该足够用了,说明内存问题不大,那就剩下nofiles打开的文件数这块有点门路了。谈到nofiles参数,客户也想起来了,前阵子好像也出现过nofiles参数不足的问题,把这个参数加大到20000后,那个问题就解决了。基于这个现象,考虑再次加大这个参数也不是长久之计,最好还是能够弄清楚为什么这个应用会存在打开文件数超出限制的问题。

由于AIX平台没有安装lsof工具,生产环境安装该工具也不允许临时安装工具。幸亏aix上有一个procfiles工具,可以检查某个进程打开的文件的情况。那就拿procfiles工具查一下,这个命令的用法挺简单procfiles 即可查看该进程打开的文件数,加上-n参数即可显示打开的文件名,于是通过procfiles –n pid查询了进程打开的文件数,结果如下

3eb52f67a24a7211fbf7c6fd7b917ff8.png

从上图可以看到进程号为2139056,应用程序的命令行为xxxx start,就是我们要分析的这个模块。当前打开的文件描述符的限制为20000而当时该命令显示打开的文件描述符有652个左右。过了一个小时再次查询居然达到900多个,照这样的速度下去,文件描述符一定很快会达到20000的限制,当达到20000的限制后,应用程序连接数据库的时候也需要打开文件句柄才能够与数据库进行通信,此时由于资源限制,无法打开句柄与数据库通信,就报了一个奇怪的错误12560 TNS:protocol adapter error。

好啦,原因找到了,就是大量打开的文件描述符,达到了资源限制,无法与数据库通信导致的。那么大量打开的文件是什么文件或者什么类型的文件呢,从上图来看,打开的文件是dev 65535,65535,在/dev目录下也不存在设备号为65535,65535的文件,好在procfiles命令的输出中提示了打开的文件类型为FIFO,这不就是先进先出的管道文件吗。

把这个发现告知应用程序的开发人员后,开发人员查看应用程序版本库后,得知是9月8号生产环境的应用程序增加了一个任务,在任务中有popen打开一个fifo管道发送数据的调用,这个调用结束后没有使用pclose函数来关闭这个管道,具体代码如下:

9028bc2b96af6989afcf0bbd21c870eb.png

上述代码中,读取的文件内容到变量sLine中,程序的553行判断当sLine的长度为0时,直接返回SUCCESS而没有pclose关闭文件句柄的操作。于是这个程序在运行一段时间后就会出现打开文件数超过nofiles限制而报错了。于是开发人员在555~556行之间添加一行pclose(fd)就可以解决问题。

修改后,通过一系列的编译、链接操作后,生成新的应用程序文件,替换到生产环境中去,启动新的应用程序,经过一段时间,通过procfiles命令,查看应用程序打开的文件句柄,发现只有3个打开的文件句柄,至此12560问题解决。

这又是一个ULIMIT资源限制导致的故障,只是报错比较隐蔽,不容易找到问题的原因。类似的问题其实都需要我们去仔细分析一下出问题的应用到底打开了什么文件,而不是简单的通过把ulimit设成-1或者加大到足够大来解决,否则下一次再报错时候,可能导致更严重的后果。

TNS-12541: TNS: 无监听程序 TNS-12560: TNS: 协议适配器错误 TNS-00511: 无监听程序 文章转自:http://www.luocs.com/archives/464.html 此文版权归作者 – yaogang所有,转载请注明yaogang©www.luocs.com。 Luocs说:这是我一个朋友的一个监听器问题解决案例,这是昨天发生的事情,我一直跟朋友一起Troubleshooting,折腾了半天最后是BUG所致。再次汗颜,Windows平台惹不起啊!好,那么下面开始分享我朋友的案例! 环境描述: OS : Windows Server 2008 64Bit (做了HA) DB : 11.1.0.7.0 排错过程: 前天应用不能访问数据库了 (后台应用能访问数据库),故障发生。 马上登录到服务器里查看监听状态,发现有TNS-12541 ,TNS-12560错误 Luocs补充:我跟朋友要了错误代码,但他没有保存,就直接贴图。 从计算器的管理 –> 服务选项 –> 检查oracle 监听服务程序,发现该服务已经停止。 手动把监听服务启动,这时候服务状态上显示为已启动,但在CMD窗口执行lsnrctl status的时候依然返回错误信息: C:\>lsnrctl status LSNRCTL for 64-bit Windows: Version 11.1.0.7.0 - Production on 12-11月-2012 18:1 8:32 Copyright (c) 1991, 2008, Oracle. All rights reserved. 正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.203.218)(PORT=1521))) TNS-12541: TNS: 无监听程序 TNS-12560: TNS: 协议适配器错误 TNS-00511: 无监听程序 64-bit Windows Error: 61: Unknown error 正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))) 过段时间回显非常慢。 然后我检查了下告警日志,大量的ora错误 Fatal NI connect error 12170. VERSION INFORMATION: TNS for 64-bit Windows: Version 11.1.0.7.0 - Production Oracle Bequeath NT Protocol Adapter for 64-bit Windows: Version 11.1.0.7.0 - Production Windows NT TCP/IP NT Protocol Adapter for 64-bit Windows: Version 11.1.0.7.0 - Production Time: 12-11月-2012 15:23:33 Tracing not turned on. Tns error struct: ns main err code: 12535 TNS-12535: TNS: 操作超时 ns secondary err code: 12560 nt main err code: 0 nt secondary err code: 0 nt OS err code: 0 Client address: ORA-609 : opiodr aborting process unknown ospid (4116_6104) 这时候朋友怀疑是不是监听器配置问题,就把原先的监听器删除重建了下,问题依然。 网上有个解决TNS-12535错误的案例,平台和版本都很类似,如下: 1、在 sqlnet.ora文件 增加如下行: DIAG_ADR_ENABLED = OFF 2、在listener.ora文件增加如下行: DIAG_ADR_ENABLED_ = OFF 如何监听是listener时,则前面的名称为:DIAG_ADR_ENABLED_LISTENER = OFF 3、重新启动windows服务管理的监听程序.先停止,然后再重新启动. 4、检查结果.发现可以了,返回的值在10毫秒.有时为0毫秒.成功!! 但这并不是问题发生原因,在继续排查过程偶然发现监听日志大小居然为4G。然后把这现象告诉了Luocs。 过了一会儿,Luocs回应是Oracle一个BUG,BUG号为9879101 : THE CONNECT THROUGH LISTENER WAS SLOW WHEN LISTNER LOG GROWED 4GB。 Luocs还提供了MOS上一篇文章,ID 1319797.1 : WINDOWS: Listener Hangs & Lsnrctl Commands Are Slow or Hang,里面给出了解决方法: You can solve this problem by deleting the large listener in $ORACLE_BASE\diag\tnslsnr\\listener\trace\.log 1) Stop the listener process using the command line or Control Panel Service. 2) Delete the log file(s) that are at or approaching the 4G size limit at this location: $ORACLE_BASE\diag\tnslsnr\\listener\trace\.log 3) Issue any lsnrctl command and you will see a new listener.log in its place under: $ORACLE_BASE\diag\tnslsnr\\listener\trace\ Since ADR Diagnostics are enabled for this listener these steps cannot be done dynamically using the lsnrctl utility. e.g. LSNRCTL>set log_file mylog Will yield: TNS-01251: Cannot set trace/log directory under ADR. However, it is possible to disable the flat file listener logging using the following commands: LSNRCTL>set current_listener LSNRCTL>set log_status OFF LSNRCTL>save_config 我就按照以上说明如下进行: 1)LSNRCTL进入交互模式 2)执行set current_listener LISTENER 3)set log_status off 4)stop 停止监听器 5)手工删除ADR指定的监听日志路径下的listener.log文件 6)start重启监听器 7)status查看状态 到此问题解决
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值