SQLNET跟踪tnsping过程

简介: 内容介绍 sqlnet是oracle提供的与网络层面交互的一个工具,比如如何解析客户端发起的连接,如何对客户端发起的连接进行辨别,如何对客户端连接进行阻隔限制,或者启用日志及跟踪(log and trace)功能等等一系列的功能,在以往的几期技术通讯录里面,我们也曾提到过通过sqlnet工具跟踪并分析oracle空闲回话中断的原因,本次我们继续通过sqlnet工具来详细的分析一次通过对tnsping的跟踪结果进行分析,查找为何外部网络无法连接数据库的原因。

内容介绍

sqlnet是oracle提供的与网络层面交互的一个工具,比如如何解析客户端发起的连接,如何对客户端发起的连接进行辨别,如何对客户端连接进行阻隔限制,或者启用日志及跟踪(log and trace)功能等等一系列的功能,在以往的几期技术通讯录里面,我们也曾提到过通过sqlnet工具跟踪并分析oracle空闲回话中断的原因,本次我们继续通过sqlnet工具来详细的分析一次通过对tnsping的跟踪结果进行分析,查找为何外部网络无法连接数据库的原因。虽然说从很大程度上说,外部网络无法正常连接到数据库服务器,很大程度上都是因为网络问题造成的原因,无论是端口限制,安全加固等等,如果没有很好的考虑数据库方面的资源,往往会造成各种奇怪的连接问题。


故障说明

本次故障发生在一个客户的RAC环境中,客户的RAC环境一直采用的是只连接一号节点,二号节点一直没有连接,在最近的一次改造过程中,客户决定启用二号节点,于是调整了连接串,却发现客户端无法正常连接开放的二号节点上。应用和数据库处于同一个网段。IP通过主机层面的ping没有问题但是数据库连接却直接报错,tnsping连接串也返回报错信息:TNS-12537: TNS: 连接关闭。


故障分析

由于故障报错信息相对简单:TNS-12537: TNS: 连接关闭,往往这种报错涉及的原因也很多,比如windows下的监听日志达到4G限制,后续连接如果无法写监听日志,就会产生TNS-12537报错,再比如从11g开始Automatic Diagnostic Repository中的 Oracle Net diagnostic在默认的情况下是开启的,当数据库和客户端的连接超过特定时间,就会把这样的信息写入到alert日志中,但这并不是一个致命的问题,往往也不会造成tnsping不通这种结果。首先我们检查了数据库tnsping不通的节点的监听,发现没有问题,可以正常连接。我们检查了客户设置的连接串模式:

ORACLE_63 =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.63)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SID = xxxx2)

    )

  )

ORACLE_157 =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.157)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SID = xxxx1)

    )

  )

以上的连接串虽然说从连接模式上来说存在着一定的不合理性,没有真正发挥RAC应用的负载均衡的特点,但是从连接串的写法上来看,并没有任何问题。并且在测试环境上,该连接串也没有任何问题。

       在检查过程中我们发现,从正常的一节点通过网络服务名连接到二节点不存在任何的问题,而从应用端发起连接就不行。到这一步,我们可以有一个大致的判断,数据库服务器层面不存在问题,两节点之间可以通过网络服务名连通对方。而通过外网交换机的应用网络却无法正常连接到数据库,所以我们有理由相信,问题出现的层面应该在网络层面,或者应用层面,但是应用可以正常的连接到一节点,考虑到二节点之前也没有连接应用,我们怀疑是否是集成商当初做安全加固将二节点的某些网络资源进行了限制,导致虽然IP能够ping通但是数据库却连不上。如果问题出现在网络层面,我们需要和网络人员沟通,至少我们需要可以拿出数据库层面关于网络问题的详细报错信息。既然问题出现在tnsping就已经不通了,那么我们尝试通过对tnsping进行详细的跟踪。

                   

跟踪参数设置:


和连接跟踪一样,默认的tnsping也是关闭的,如果需要开启跟踪也同样是在客户端sqlnet.ora文件中编入参数:(因此你的客户端至少需要是完全安装版本的,简单绿色版的客户端不行)

TNSPING.TRACE_LEVEL=SUPPORT

TNSPING.TRACE_DIRECTORY=d:\oracle\trace


TNSPING.TRACE_LEVEL指的是跟踪的级别,SUPPORT为最高级别,该参数可选的级别包括:off,user,admin,support 一般来说既然是跟踪错误原因,个人觉得还是将细粒度调整到最大为好,越详细的日志,对于我们分析问题帮助越大。

TNSPING.TRACE_DIRECTORY指的是跟踪产生的trace文件存放的位置

编入以上参数,我们即可执行tnsping过程:

C:\Users\frank-ying>tnsping oracle_157

 已使用 TNSNAMES 适配器来解析别名

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)

(HOST = 10.20.10.157)(PORT = 1521))) (CONNECT_DATA = (SID = credit1)))

TNS-12537: TNS: 连接关闭


结果获取后我们可以对文件进行分析,以下部分贴出整个跟踪文件结果集进行详细分析:

详细日志分析过程

########!跟踪文件头信息记录包括客户端信息,版本,跟踪时#####################

TNS Ping Utility for 32-bit Windows: Version 10.2.0.1.0 - Production on 17-7 -2014 08:52:31

 

Copyright (c) 1997, 2005, Oracle.  All rights reserved.

#######本次跟踪的信息读取,包括跟踪级别,基本的跟踪参数读取位置##############

--- TRACE CONFIGURATION INFORMATION FOLLOWS ---

New trace stream is d:\oracle\trace\tnsping.trc

New trace level is 16

--- TRACE CONFIGURATION INFORMATION ENDS ---

--- PARAMETER SOURCE INFORMATION FOLLOWS ---

Attempted load of system pfile source D:\oracle\product\10.2.0\db_1\network\admin\sqlnet.ora

Parameter source loaded successfully

 

 -> PARAMETER TABLE LOAD RESULTS FOLLOW

Successful parameter table load

 -> PARAMETER TABLE HAS THE FOLLOWING CONTENTS

  TNSPING.TRACE_LEVEL = SUPPORT

  NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)

  TNSPING.TRACE_DIRECTORY = d:\oracle\trace

  SQLNET.AUTHENTICATION_SERVICES = (NTS)

--- PARAMETER SOURCE INFORMATION ENDS ---

--- LOG CONFIGURATION INFORMATION FOLLOWS ---

Log stream will be "standard output"

Log stream validation not requested

--- LOG CONFIGURATION INFORMATION ENDS ---


以上是整个跟踪文件的头文件,记录包括客户端信息,版本,跟踪时间,跟踪级别,基本的跟踪参数读取位置等信息。


#########################开始跟踪tnsping过程##############################

nlstdipi: entry

nlstdipi: exit

nnfun2awanm: entry

nnfgiinit: entry

nncpcin_maybe_init: first request sent to name server will have ID 0

nncpcin_maybe_init: initial retry timeout for all name servers is 1500 csecs

nncpcin_maybe_init: max request retries per name server is 1

nngsini_init_streams: initializing stream subsystem, cache size is 10

nngtini_init_msg: initializing PDU subsystem, initial pool size is 2

nncpcin_maybe_init: default name server domain is [root]

nnfgiinit: Installing read path

nnfgsrsp: entry

####################读取本地tnsnames.ora文件##############################

nnfgsrsp: Obtaining path parameter from names.directory_path or native_names.directory_path

nnfgsrdp: entry

nnfgsrdp: Setting path:

nnfgsrdp: checking element TNSNAMES

nnfgsrdp: checking element EZCONNECT

nnfgsrdp: Path set

nnfun2a: entry

nlolgobj: entry

nnfgrne: entry

nnfgrne: Going though read path adapters

nnfgrne: Switching to TNSNAMES adapter

nnftboot: entry

nlpaxini: entry

nlpaxini: exit

nnftmlf_make_local_addrfile: entry

nnftmlf_make_local_addrfile: construction of local names file failed

nnftmlf_make_local_addrfile: exit

nlpaxini: entry

nlpaxini: exit

nnftmlf_make_system_addrfile: entry

nnftmlf_make_system_addrfile: system names file is D:\oracle\product\10.2.0\db_1\network\admin\tnsnames.ora

nnftmlf_make_system_addrfile: exit

nnftboot: exit

nnftrne: entry

####获取本次需tnsping的连接串名扫描整个tnsnames.ora文件匹配该连接串名####

nnftrne: Original name: oracle_157

nnfttran: entry

nncpdpt_dump_ptable: --- D:\oracle\product\10.2.0\db_1\network\admin\tnsnames.ora TABLE HAS THE FOLLOWING CONTENTS ---

nncpdpt_dump_ptable: load_balance = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.157)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.63)(PORT = 1521)) (LOAD_BALANCE = yes) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = credit_server_taf) (FAILOVER_MODE = (TYPE = SELECT) (METHOD = BASIC) (RETRIES = 180) (DELAY = 5))))

nncpdpt_dump_ptable: balance = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.157)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.63)(PORT = 1521)) (LOAD_BALANCE = yes) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = creditmanager) (FAILOVER_MODE = (TYPE = SELECT) (METHOD = BASIC) (RETRIES = 180) (DELAY = 5))))

nncpdpt_dump_ptable: --- END D:\oracle\product\10.2.0\db_1\network\admin\tnsnames.ora TABLE ---

nnfttran: exit

############################结果正常获取##################################

nnftrne: Using tnsnames.ora address (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.10.155)(PORT = 1521))) (CONNECT_DATA = (SID = credit1))) for name oracle_157

######################解析连接串结果并开始跟踪############################

nsmal: 212 bytes at 0xee81d8

nsmal: normal exit

nscall: connecting...

nladini: entry

nladini: exit

nladget: entry

nladget: exit

nsc2addr: entry

nsc2addr: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.20.10.155)(PORT=1521))(CONNECT_DATA=(SID=credit1)))

nttbnd2addr: entry

snlinGetAddrInfo: entry

snlinGetAddrInfo: exit

nttbnd2addr: using host IP address: 10.20.10.155此处可以看到配置的是实际地址所以不用在去解析DNS或者分析hosts文件

nsmal: normal exit

nsbal: normal exit

nsiorini: exit (0)

nscpxget: entry

nscpxget: normal exit

nsopenalloc_nsntx: nlhthput on mplx_ht_nsgbu:ctx=f32ef0, nsntx=f331d8

nsopenmplx: normal exit

########################开始创建连接######################################

nsopen: opening transport...

nttcon: entry

nttcon: toc = 1

nttcnp: entry

nttcnp: creating a socket.

nttcnp: exit

nttcni: entry

nttcni: trying to connect to socket 1808.

snlinGetNameInfo: entry

snlinGetNameInfo: Using numeric form of host's address 10.20.10.131

snlinGetNameInfo: exit

nttcni: connected on ipaddr 10.20.10.131解析本地IP地址  

nttcni: exit

nttcon: NT layer TCP/IP connection has been established.TCP/IP协议

nttcon: set TCP_NODELAY on 1808

nttcon: exit

####################以下开始发包过程发送87字节的包#######################

nsdo: cid=0, opcode=67, *bl=29, *what=8, uflgs=0x0, cflgs=0x3

nsdo: rank=64, nsctxrnk=0

nsdo: nsctx: state=14, flg=0x4005, mvd=0

nsdo: gtn=10, gtc=10, ptn=10, ptc=2011

nscon: entry

nscon: doing connect handshake...

nscon: sending NSPTCN packet

nspsend: entry

nspsend: plen=87, type=1

nttwr: entry

nttwr: socket 1808 had bytes written=87

nttwr: exit

nspsend: packet dump

nspsend: 00 57 00 00 01 00 00 00  |.W......|

nspsend: 01 39 01 2C 00 00 08 00  |.9.,....|

nspsend: 7F FF C6 0E 00 00 01 00  |........|

nspsend: 00 1D 00 3A 00 00 00 00  |...:....|

nspsend: 00 00 00 00 00 00 00 00  |........|

nspsend: 00 00 00 00 00 00 00 00  |........|

nspsend: 00 00 00 00 00 00 00 00  |........|

nspsend: 00 00 28 43 4F 4E 4E 45  |..(CONNE|

nspsend: 43 54 5F 44 41 54 41 3D  |CT_DATA=|

nspsend: 28 43 4F 4D 4D 41 4E 44  |(COMMAND|

nspsend: 3D 70 69 6E 67 29 29     |=ping)) |

nspsend: 87 bytes to transport发包成功返回

nspsend: normal exit

nscon: exit (0)

nsdo: nsctxrnk=0

nsdo: normal exit

nsdo: entry

nsdo: cid=0, opcode=68, *bl=1024, *what=9, uflgs=0x2000, cflgs=0x3

nsdo: rank=64, nsctxrnk=0

nsdo: nsctx: state=2, flg=0x4005, mvd=0

nsdo: gtn=10, gtc=10, ptn=10, ptc=2011

nscon: entry

############################开始回包过程##################################

nscon: recving a packet

nsprecv: entry

nsprecv: reading from transport...

nttrd: entry

ntt2err: entry

ntt2err: soc 1808 error - operation=5, ntresnt[0]=530, ntresnt[1]=53, ntresnt[2]=0

ntt2err: exit

nttrd: exit

nsprecv: error exit

nserror: entry

nserror: nsres: id=0, op=68, ns=12570, ns2=12560; nt[0]=530, nt[1]=53, nt[2]=0; ora[0]=0, ora[1]=0, ora[2]=0

nscon: error exit

nsdo: nsctxrnk=0

nsdo: error exit

nscall: unexpected response

我们详细分析上面的报错过程从目前来看整个的发包过程没有问题但是在包返回过程中直接报错返回错误ntt2err: soc 1808 error - operation=5, ntresnt[0]=530, ntresnt[1]=53, ntresnt[2]=0

从错误的信息看,应该是在网络层面出了问题,据此我们搜索了MOS相关文档:

ORA-3113 reported when using NitroSecurity Firewall. (文档 ID 1388804.1)

该文档报错信息一致,原因是NitroSecurity防火墙的阻隔

通过对以上结果的分析,我们有理由确信在中间的网络层面出现了阻隔导致返回包的过程中出现了问题,就此将问题提交网络工程师

 



技术结论

从以上的分析结果看,sqlnet跟踪的分析过程其实并没有我们想像的那么复杂,tnsping通过解析主机及端口号,建立与数据库服务器的连接。通过一次发包及回包的过程来检测网络是否存在问题,本次分析我们更多的是为了分析tnsping的结果而分析,在真正实际环境中,大家可以从跟踪文件的最后开始倒推分析。往往这种连接问题,通过相应的跟踪日志,基本都能大致的分析出问题的成因所在。

 ------------------------------------------------------------------------------------

原博客地址:http://blog.itpub.net/23732248/
原作者:应以峰 (frank-ying)
-------------------------------------------------------------------------------------

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
SQL 数据库 C#
C# .NET面试系列十一:数据库SQL查询(附建表语句)
#### 第1题 用一条 SQL 语句 查询出每门课都大于80 分的学生姓名 建表语句: ```sql create table tableA ( name varchar(10), kecheng varchar(10), fenshu int(11) ) DEFAULT CHARSET = 'utf8'; ``` 插入数据 ```sql insert into tableA values ('张三', '语文', 81); insert into tableA values ('张三', '数学', 75); insert into tableA values ('李四',
62 2
C# .NET面试系列十一:数据库SQL查询(附建表语句)
|
9月前
|
SQL 开发框架 前端开发
ASP.NET Core+Element+SQL Server开发校园图书管理系统(完)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(完)
94 0
|
9月前
|
开发框架 JavaScript .NET
ASP.NET Core+Element+SQL Server开发校园图书管理系统(四)(下)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(四)(下)
69 0
|
9月前
|
开发框架 JavaScript .NET
ASP.NET Core+Element+SQL Server开发校园图书管理系统(三)(下)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(三)(下)
52 0
ASP.NET Core+Element+SQL Server开发校园图书管理系统(三)(下)
|
SQL Web App开发 Java
十四、.net core(.NET 6)搭建ElasticSearch(ES)系列之给ElasticSearch添加SQL插件和浏览器插件
给ES添加SQL插件的方法:下载SQL插件地址:https://github.com/NLPchina/elasticsearch-sql当前最新的是7.12版本,我的ES是7.13版本,暂且将就用一下,也许能用呢?
217 0
十四、.net core(.NET 6)搭建ElasticSearch(ES)系列之给ElasticSearch添加SQL插件和浏览器插件
|
SQL Oracle 关系型数据库
Oracle 等待事件研究:SQL*Net break/reset to client
SQL*Net break/reset to client事件是一个容易被误解的事件,这个事件看起来和网络有关,但实际上大多数情况下这个事件与网络无关。
377 0
Oracle 等待事件研究:SQL*Net break/reset to client
.Net ADO拼接带参数的SQL语句
.Net ADO拼接带参数的SQL语句
120 0
|
SQL .NET 数据库
.net core 2.1-----Sql Server数据库初体验
刚开始接触asp.net core,在学习的过程中遇到了一些小问题,在这里记录一下! 在我们项目的开发过程中,肯定会和数据库打交道,所以我尝试了一下用asp.net core链接数据库,并读取表中的数据(当然你必须保证有能访问的sql server数据库)! 首先,新建项目:ASP.
1274 0
|
SQL 安全 .NET
ASP.net防止SQL注入方法
1、sql注入比较难防,需要替换select,delete等一打字符  其实对于字符型替换再多都没有替换单引号为两个单引号来的好!对于数字型替换再多都没有用,一定要类型转换。
1456 0
|
SQL 存储 数据库
.NET面试题解析(11)-SQL语言基础及数据库基本原理
转自:http://www.cnblogs.com/anding/p/5281558.html 常见面试题目: 0. 基本SQL语法题目,在 正文“基础SQL语法”中有13道题,这里就略过了。 1.
1240 0