Fatal NI connect error 12170
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 – Production
在巡检数据库alert log过程中,发现一些错误提示。
Tue May 19 23:04:55 2015
*************************************
Fatal NI connect error 12170.
VERSION INFORMATION:
TNS for Linux: Version 11.2.0.4.0 - Production
Oracle Bequeath NT Protocol Adapter for Linux: Version 11.2.0.4.0 - Production
TCP/IP NT Protocol Adapter for Linux: Version 11.2.0.4.0 - Production
Time: 19-MAY-2015 23:04:55
Tracing not turned on.
Tns error struct:
ns main err code: 12535
TNS-12535: TNS:operation timed out
ns secondary err code: 12560
nt main err code: 505
TNS-00505: Operation timed out
nt secondary err code: 110
nt OS err code: 0
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=172.xx.xx.xx)(PORT=50741))
问题分析
这类型错误在11gR2版本中经常出现。笔者之前的一些投产系统中,也常常出现这样的问题。当前进行开发的系统架构比较传统,是一个典型CS架构方式。客户端桌面应用是一个富客户端软件,所有业务逻辑都在客户端。客户端直接连接数据库。
这种架构方式是比较传统的方式,行业内对于这种方式的缺陷已经讨论很多年了。
单从数据库角度看,这样的架构方式意味着更加多的数据库连接数量和更加频繁的访问结构。
利用IP地址,我们可以从监听器日志listener.log中,可以定位到这个IP地址连接是什么时候连接过来的。
[oracle@localhost trace]$ pwd
/u01/app/diag/tnslsnr/localhost/listener/trace
[oracle@localhost trace]$ cat listener.log | grep 172. xx.xx.xx
19-MAY-2015 13:51:10 * (CONNECT_DATA=(CID=(PROGRAM=JDBC Thin Client)(HOST=__jdbc__)(USER=visvim))(SERVICE_NAME=sicsdb)) * (ADDRESS=(PROTOCOL=tcp)(HOST=172.xx.xx.xx)(PORT=50741)) * establish * sicsdb * 0
从MOS上的信息反馈看,这个类型错误提示是一种正常的Oracle工作机制。当客户端进程Client Process与服务器进程Server Process建立联系之后,两者就形成了“同生共死”的关系(专有连接模式)。除非客户端主动发起中断或者Server Process被异常kill。
在实际运行环境中,这种理想状态常常被打破。如果Client Process只是保持连接,不执行语句,会话就处于idle状态。这种连接很容易被诸如防火墙等网络层面设备切断。
在Oracle11gR2中,如果长期没有连接动作的Server Process被外力切断,Oracle就会自动将信息作为提示错误写入到alert log中,作为一种提示。在11R1版本中,这种信息是会写入到sqlnet.log中。
问题解决措施
归纳MOS和网络中的各种方法,大体有两重策略,分别为使用DCD和禁用ADR。
DCD(Dead Connection Detection)
死连接检测是一种通信查探技术,引入特性的初衷是解决死链接标记回收问题,这是 Oracle 提供的一个很不错的功能,死链接检测主要的产生环境是在客户端在没有正常断开连接后断开连接,问题出在客户端的网络上,死连接检测被初始化在服务器端。SQL*NET
读取参数文件的设置。在 sqlnet.ora 文件里设置 SQLNET.EXPIRE_TIME 为非零参数时间间隔。当超过设置时间,SQL*NET
发送一个"探索"包到客户端。对于一个数据库链接,链接的目的地构成连接的服务器端。"探索"本质上是个空包。不会表示任何 SQL*NET 级别的数据,但是它创建了数据流在底层的协议。如果客户端是 ACTIVE, 包被丢弃,探索时间被重置,如果客户端异常终止,服务器端将会接受一个错误。服务端标记操作系统释放链接资源。
配置 DCD,可以在一定程度上缓解由于长时间连接中断造成的报错问题。同时也可以排除发现潜在前端应用在数据库连接方面的故障和问题。
DCD全称Dead Connection Detection,是一种基于主动测探方式检查Oracle僵尸客户端进程Client Process的策略。配置DCD的关键是设置sqlnet.expire_time参数在SQL Net体系下,Oracle会依据这个时间间隔给所有的Client Process发送网络通信包,用来确定Client是否存活。
正是借助这个包通信,可以让防火墙认为这个网络连接还是处在active状态,不会进行强制断开动作。类似的机制还有Linux上的tcp keep live机制,也是使用类似的策略进行检查。
[oracle@localhost trace]$ cd /u01/app/oracle/network/admin/
[oracle@localhost admin]$ ls -l
total 16
-rw-r--r--. 1 oracle oinstall 343 Sep 2 2014 listener.ora
drwxr-xr-x. 2 oracle oinstall 4096 Jun 16 2014 samples
-rw-r--r--. 1 oracle oinstall 381 Dec 17 2012 shrept.lst
-rw-r--r--. 1 oracle oinstall 0 Sep 2 2014 sqlnet.ora
-rw-r-----. 1 oracle oinstall 308 Sep 5 2014 tnsnames.ora
[oracle@localhost admin]$ cat sqlnet.ora
[oracle@localhost admin]$ cat sqlnet.ora
sqlnet.expire_time=10 #10表示10分钟
另一种方式也是Oracle推荐的,就是关闭11g的ADR机制。ADR(Automatic Diagnostic Repository)是Oracle进行自动诊断、自动提醒的工具组件。Oracle认为如果用户不需要在SQL Net组件中应用ADR,可以再sqlnet.ora中进行配置关闭。
[oracle@localhost admin]$ cat sqlnet.ora
sqlnet.expire_time=10
DIAG_ADR_ENABLED = OFF
DIAG_ADR_ENABLED_LISTENER=OFF
之后,重新reload监听器配置,或者重启监听器。
[oracle@localhost admin]$ lsnrctl reload
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 21-MAY-2015 10:13:34
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))
结论
数据库 “Fatal NI connect error 12170” 问题,从本质上是由于长连接数据库交互方式造成的,严格意义上不应算什么错误问题。如果是一些三层架构体系应用,可以考虑使用连接池进行动态资源调配的方式,对问题进行缓解。
参考资料
Alert Log Errors: 12170 TNS-12535/TNS-00505: Operation Timed Out (Doc ID 1628949.1)
https://blog.51cto.com/lhrbest/2696549
https://mp.weixin.qq.com/s?__biz=MzU5MDYyMzUyMA==&mid=2247483760&idx=1&sn=c169a1bca1d5b23696abd30a21050807&chksm=fe3a273fc94dae2945ed088d05bdf5c5cdd21059cb58454fe483a08431dcce0ddaa24ebc6019&scene=21#wechat_redirect
RAC下Fatal NI connect error 12170.报错处理
https://blog.csdn.net/huangyanlong/article/details/46372849
Fatal NI connect error 12170错误解决办法
https://blog.csdn.net/weixin_40913898/article/details/124581511
Oracle告警处理:Alert日志出现大量Fatal NI connect error 12170告警
https://blog.51cto.com/xiaozc/5345561
Oracle 监听器无法启动(TNS-12555,TNS-12560,TNS-00525)
[oracle@localhost ~]$ lsnrctl start
LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 06-AUG-2014 19:40:52
Copyright (c) 1991, 2009, Oracle. All rights reserved.
Starting /opt/oracle/11g/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 11.2.0.1.0 - Production
System parameter file is /opt/oracle/11g/network/admin/listener.ora
Log messages written to /opt/oracle/diag/tnslsnr/localhost/listener/alert/log.xml
Error listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
TNS-12555: TNS:permission denied
TNS-12560: TNS:protocol adapter error
TNS-00525: Insufficient privilege for operation
Linux Error: 1: Operation not permitted
Listener failed to start. See the error message(s) above...
观察发现,提示没有权限:
查看.oracle文件:
[root@localhost ~]# ls -lrtd /var/tmp/.oracle
drwxrwxrwt. 2 root root 4096 8\u6708 5 21:48 /var/tmp/.oracle
[root@localhost ~]# ls -lrtd /tmp/.oracle
drwxrwxrwt. 2 root root 4096 8\u6708 5 20:33 /tmp/.oracle
发现权限虽然是777,但是用户组和所有者不对,改成oracle:dba
[root@localhost ~]# chown -R oracle:dba /var/tmp/.oracle
[root@localhost ~]# chown -R oracle:dba /tmp/.oracle
[root@localhost ~]# ls -lrtd /tmp/.oracle
drwxrwxrwt. 2 oracle dba 4096 8\u6708 5 20:33 /tmp/.oracle
[root@localhost ~]# ls -lrtd /var/tmp/.oracle
drwxrwxrwt. 2 oracle dba 4096 8\u6708 5 21:48 /var/tmp/.oracle
再次启动,成功!