TNS-12537 TNS-00507 Connection closed错误
最近帮客户将一套10.2.0.4.0版本RAC+10.2.0.4.0版本RAC的DG环境成功升级到11.2.0.3.5,升级后客户让解决下TNS-12537: TNS:connection closed及TNS-00507: Connection closed错误,这个错误在升级之前就一直存在,很显然是防火墙限制空闲连接时间的问题:
Fatal NI connect error 12537, connecting to: (DESCRIPTION=(ADDRESS_LIST=(address=(protocol=tcp)(host=xxx.xx.xx.xx)(port=1521)))(CONNECT_DATA=(SERVICE_NAME=xxxxx)(INSTANCE_NAME=xxxxx1)(failover_mode=(backup=xxxxx2)(type=select)(method=preconnect))(CID=(PROGRAM=oracle)(HOST=xxxxdbbak01)(USER=xxxxl)))) VERSION INFORMATION: TNS for Linux: Version 11.2.0.3.0 - Production Oracle Bequeath NT Protocol Adapter for Linux: Version 11.2.0.3.0 - Production TCP/IP NT Protocol Adapter for Linux: Version 11.2.0.3.0 - Production Time: 30-APR-2014 08:36:28 Tracing not turned on. Tns error struct: ns main err code: 12537 TNS-12537: TNS:connection closed ns secondary err code: 12560 nt main err code: 507 TNS-00507: Connection closed nt secondary err code: 0 nt OS err code: 0 Wed Apr 30 08:39:03 2014
告警日志显示这是通过dblink访问远端数据库时,连接被中断,再次通过dblink访问远端数据库时,由于使用到了之前的session,而这个session在源端数据库已经被中断,就抛出这个错误。这个错误对业务没有影响,检测到之前的session被中断,会重新开一个新的session,但客户的日志表大量记录了这个错误,需要解决。
通过查询数据库的profile也证实了数据库层并没有做任何的限制,捣蛋者就是防火墙。
SQL> select username,profile from dba_users where username='ETL_REP'; USERNAME PROFILE ------------------------------ ------------------------------ ETL_REP DEFAULT SQL> select * from dba_profiles where profile='DEFAULT'; PROFILE RESOURCE_NAME RESOURCE LIMIT ---------- ------------------------- -------- -------------------- DEFAULT COMPOSITE_LIMIT KERNEL UNLIMITED DEFAULT SESSIONS_PER_USER KERNEL UNLIMITED DEFAULT CPU_PER_SESSION KERNEL UNLIMITED DEFAULT CPU_PER_CALL KERNEL UNLIMITED DEFAULT LOGICAL_READS_PER_SESSION KERNEL UNLIMITED DEFAULT LOGICAL_READS_PER_CALL KERNEL UNLIMITED DEFAULT IDLE_TIME KERNEL UNLIMITED DEFAULT CONNECT_TIME KERNEL UNLIMITED DEFAULT PRIVATE_SGA KERNEL UNLIMITED DEFAULT FAILED_LOGIN_ATTEMPTS PASSWORD UNLIMITED DEFAULT PASSWORD_LIFE_TIME PASSWORD UNLIMITED DEFAULT PASSWORD_REUSE_TIME PASSWORD UNLIMITED DEFAULT PASSWORD_REUSE_MAX PASSWORD UNLIMITED DEFAULT PASSWORD_VERIFY_FUNCTION PASSWORD NULL DEFAULT PASSWORD_LOCK_TIME PASSWORD UNLIMITED DEFAULT PASSWORD_GRACE_TIME PASSWORD UNLIMITED
ORACLE也给出了解决这个错误的方法,也就是DCD(Dead Conneciton Detection),通过设置服务端的sqlnet.ora文件,来主动向客户端发送检测请求,如果客户端还活着,则不做操作,如果检测发现客户端的连接已经不存在或没有反映,则回收这个session的资源。这样,如果DCD的检测时间小于防火墙设置的空闲连接最大存活时间,那么由于DCD检测客户端存活性需要从服务端发送一个空包到客户端,防火墙就会重新计算这个连接的空闲时间,就不会中断这个会话了。设置DCD需要在服务端的sqlnet.ora文件中添加以下信息:
sqlnet.expire_time = 3
这个值的单位是分钟,这里设置的是每三分钟服务端会向已连接数据库的session所在的客户端发送一个空包,来检测客户端的存活性,如果防火墙限制的空闲连接时间大于3分钟,那么连接到数据库的会话就不会因为大于3分钟的空闲时间而被中断。这种方案完全可以解决这个问题,但这种方法需要重新注册监听,负责远端数据库的客户并不允许在服务器上直接操作(跨部门)。那么就只好换成设置客户端的方案了。
通过设置客户端linux内核参数,也可以实现这个功能。
net.ipv4.tcp_keepalive_time = 60
修改客户端的ipv4.tcp_keepalive_time值也可以达到类似的效果,不同的是这个设置是由客户端发起,不需要对服务端做设置。但是通过dblink访问数据库的连接并不一定会在TCP Socket上打开SO_KEEPALIVE,也就是这个设置不一定100%生效。如果要彻底解决这个问题最好还是使用DCD,可能是我人品暴发,设置net.ipv4.tcp_keepalive_time = 60(秒)后,出现几次连接中断错误后(这个操作只对新连接生效),在未遇到这个错误。是否彻底解决还需要观察一段时间。
————————————————–end———————————————————-
【下一篇】oracle 11g TNS-12535 TNSoperation timed out错误