SQL Server 连接问题案例解析(1)

   Microsoft Network Monitor(Netmon)是由微软发布的一款网络协议数据分析工具,利用Netmon可以捕获网络数据并进行查看和分析。
在处理SQL Server 的连接问题时,Netmon常常会起到关键的作用。在本篇博文中,我将为大家分享一个通过使用 Netmon 解决的经典案例。
      在这个案例中,客户发现在客户端的 SQL Server Management Studio 中执行某一个Query时就会发生错误,
错误信息是“connection forcibly close by the remote server ”。
 
为了调查连接被关闭的原因,我们在客户端和服务端抓取了Netmon。在正式分析这个案例前,我们先来介绍一些有关Netmon的知识和使用技巧。
 
                                                     Netmon界面

1. 在Netmon界面中的Frame Summary 部分,我们首先可以看到Frame Number,不管我们在浏览时是否有设置filter,Frame Number的值是不会发生改变的,

它相当于Frame的一个行号。
 
2. 在左侧Network Conversation 中,我们会看到进程的name和ID,在示例中即为Ssms.exe和3352。继续展开后看到IPv4,
那么我们可以知道这个conversation是从哪里来的。再次展开可以看到这个conversation的端口,本示例中,端口为1433到49428 。
 
在这里需要额外讲解一下,当客户端程序创建连接到SQL Server时会使用哪些端口呢?
客户端会向操作系统申请并使用一个动态端口并向SQL Server发送连接请求。如果在连接时使用的是machine name,provider默认会去连接1433端口,
这是一个provider的行为,改变这个行为需要修改注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\<Provider>\tcp\DefaultPort
3. 当客户端尝试创建一个连接到SQL Server,有了source port和destination port后,在这两个port中就会形成一组physical tcp连接。
形成连接之后每发一个包,包的sequence值就会发生变化。请注意,只有在同一个物理连接中,sequence的变化是连续的。
如果客户端和SQL Server建立了两个不同的物理连接,这两个连接中的sequence没有任何关系。
4. Netmon中数据量很大,如果查看呢?
比如在浏览一个比较大的Netmon时,我们发现了一个Reset  Flag:
21  3:46:20 PM 9/5/2014          21.8000442   Ssms.exe       172.22.204.237      172.16.221.38           TCP    
TCP: [Bad CheckSum]Flags=...A.R.., SrcPort=49428, DstPort=1433, PayloadLen=0,

Seq=3636257929, Ack=707503184, Win=0     {TCP:2,IPv4:1}
就可以从这个Frame的详细信息入手。从详细信息中可以找到它的source port是49428。
(1)此时我们可以就通过添加 filterTcp.port==49428 来过滤出这个Reset的conversation。
(2)另外一种过滤方法是直接在右键单击Frame后弹出的菜单中选择Find Conversation, 但这种方法有可能会造成丢包,因此还是推荐使用第一种方法。
找到了port就几乎相当于找到了出问题的连接。当然,对于不同时间点,同样的port有可能会是两个不同的连接,
因为上一个连接关掉后,下一个连接有可能重用这个port。按照port过滤后,从reset 开始顺序往前看。
5. 在Netmon中我们还可以看到一些protocol是TDS的Frame。TDS的好处是在查看Frame Details时,可以看到更多的信息。
例如我们查看一个TDS:SQLBatch的TDS Frame Detail,可以看到SQL的statement:

对于当SQL Server使用的端口不是默认的1433时,如何显示TDS frames,
6. 除了在4中介绍的通过port进行过滤,最常用的filter还有
ipv4.address==<xxx.xx.xx.xx>
除直接在filter中写入之外还有一种添加filter的方法,以过滤出所有flag是reset的frames为例来说明:那么我可以在某个reset frame的details中找到这个flag,
在右键单击弹出的菜单中选择Add Selected
Value to Display filter:
 
7. 一个SQL Server的包会在网络传输过程中会经过以下几层:
NIC(网卡物理设备)—》NDIS(网卡驱动)—》TCPIP (操作系统)—》afd(操作系统后台线程,每一个tcp port上都会有一个afd)—》
SQL Server—》for authentication(调用 sspi—lssas—DC)
Netmon所抓取的数据是在网卡驱动上面和TCPIP 下面的。
 
所以Netmon所抓到的包是不能作为网卡真正发出去的包的,需要比较发出去的包和客户端收到的包来判断网卡或路由等是否进行了切包。
8. 在chimney开启时,抓到的包的信息有可能是不全的,如果在查看时发现包的行为很奇怪,怀疑丢包,
那么一定要请客户关闭chimney(以管理员运行CMD并且执行命令:netsh interface tcp set global chimney=disabled)后重新收集Netmon。

接下来,我们就来讨论一下今天的案例。当具备了以上Netmon的知识和技巧后,在处理这个案例中所收到的Netmon数据就非常有针对性了。

将客户端的Netmon数据按照端口号filter后,可以很清楚的看到,客户端一直面对着重传的问题。16是12的重传,17也是12的重传,甚至18,19,20:

那么我们来看一下12的详细信息:

可以看到这个包的长度是4096。那么16呢?查看16的详细信息时我们发现,16的长度变成了1460:

      在重传时包的长度变小说明,由于之前大包无法传递,传递的包的大小被自动调小了。继续查看17,18,19和20会发现这几个包的长度都是1460。
很明显,这是一个大包发不过去导致重传的问题。
      那么现在问题来了,为什么第一次大包发不过去,之后以小包重传也不成功呢?
      查看server端Netmon后会发现,这是由于传输4096的包被切成1460+1460+1172后,server端只收到了最后一个包。
接下来,由于sequence断了,server端会认为这是一个不合法的包,因为中间的信息缺失了。
之后这个连接就在server端直接被block了(所以我们收到的错误信息是“connection forcibly close by the remote server
”),因此后续re-transmit的1460的包server再也没有接收过(后续重传全都失败了)。
      最终问题的解决办法是关闭网卡上的两个选项:Jumbo Packet和Large Send Offload(LSO)。

开启Jumbo Packet表示支持大包,关闭则表示从NIC发出的包采用标准大小1500。

如果LSO是开启的,切包会由网卡驱动(NDIS)完成。如果LSO关闭,切包会由操作系统(TCP Stack)完成,切成多大由Jombo Packet的设置来决定。

我们通常不建议由网卡来切包,因为网卡切包与网络环境有关,可能会导致包的大小不固定,建议还是由操作系统来进行切包。
将这两个选项关闭后,传输包的大小均为标准大小1500,就解决了这个大包被切,重传失败的问题。
      这就是今天的分享,更多SQL Server案例学习请持续关注本博客的更新。

server端Netmon和client端netmon

 
Jumbo Packet:巨型包
 

SQL Server 连接问题案例解析(1)的更多相关文章

  1. SQL Server 连接超时案例一则

    上周六,一工厂系统管理员反馈一数据库连接不上,SSMS连接数据库报"连接超时时间已到.在尝试使用预登录握手确认时超过了此超时时间.......", 如下截图所示: 另外远程连接也连 ...

  2. SQL Server并行死锁案例解析

    并行执行作为提升查询响应时间,提高用户体验的一种有效手段被大家所熟知,感兴趣的朋友可以看我以前的博客SQL Server优化技巧之SQL Server中的"MapReduce", ...

  3. SQL Server 连接问题-TCP/IP

    原文:SQL Server 连接问题-TCP/IP 出自:http://blogs.msdn.com/b/apgcdsd/archive/2012/02/24/ms-sql-server-tcp-ip ...

  4. 通过sql server 连接mysql

    图文:通过sql server 连接mysql   1.在SQL SERVER服务器上安装MYSQL ODBC驱动; 驱动下载地址:http://dev.mysql.com/downloads/con ...

  5. ASP.NET连接数据库时,提示“用户 'sa' 登录失败原因: 未与信任 SQL Server 连接相关联

    用ASP.NET连接数据库时,提示"用户 'sa' 登录失败.原因: 未与信任 SQL Server 连接相关联.".解决方法:首先检查是不是web.config文件内的用户名密码 ...

  6. SQL Server 2000:提示“未与信任SQL SERVER连接相关连”错误

    在使用“用户模式”登陆SQL Server 2000时提示“未与信任SQL SERVER连接相关连”错误,因为在安装SQL Server时选择“仅Windows”模式,所以所有用户都不可以登陆. 解决 ...

  7. SQL Server 连接问题圣经-命名管道

    SQL Server 连接问题圣经-命名管道 (1) APGC DSD Team 12 Jan 2011 1:24 AM 3 一.前言 在使用SQL Server 的过程中,用户遇到的最多的莫过于连接 ...

  8. 【J2EE】Java连接SQL Server 2000问题:“com.microsoft.sqlserver.jdbc.SQLServerException:用户'sa'登录失败。该用户与可信SQL Server连接无关联”

    1.问题现象 E:\JSP\HibernateDemo\HibernateDemoProject\src\sine>java ConnectSQLServerConnect failed!com ...

  9. [ASP.NET]SQL Server 连接字符串和身份验证

    SQL Server .NET Data Provider 连接字符串包含一个由一些属性名/值对组成的集合.每一个属性/值对都由分号隔开. PropertyName1=Value1; Property ...

随机推荐

  1. Java研发岗位面试归类A(附答案)

    题目来自http://www.codeceo.com/article/201-java-interview-qa.html,答案自己网上找的,如有疏漏,欢迎斧正.一起学习,共同进步. 一.Java基础 ...

  2. 自己搭建了一个简单实用的Web版记事本

    演示播放地址:http://v.youku.com/v_show/id_XMTg0MjY2OTAxNg==.html 技术说明 环境 vs2012开发 sql2008r2数据库 技术 C#基础语言 M ...

  3. shell循环语句

    所有的笔记只记录一些例子,根据例子解释一些出现的语法,不介绍具体的语法 2015-07-01 21:58:33 星期三 for循环 用例一用for循环在家目录下创建aaa1-aaa10,然后在aaa1 ...

  4. 【转】Android 底层开发的几点

    我干了3年Android sdk开发,觉得到了瓶劲没法更进一步,于是花了一年多点时间,大概摸到点门径.根据前辈的经验,Android底层完全入门需要两年. 先说下我的入门过程:第零步,下载源码,我下的 ...

  5. Ubuntu下配置python完成爬虫任务(笔记一)

    Ubuntu下配置python完成爬虫任务(笔记一) 目标: 作为一个.NET汪,是时候去学习一下Linux下的操作了.为此选择了python来边学习Linux,边学python,熟能生巧嘛. 前期目 ...

  6. 移动端 css/html (box-flex)自适应、等比布局

    移动端 css/html (box-flex)自适应.等比布局 对于移动端自适应的一种布局方式. <!DOCTYPE html> <html> <head> < ...

  7. Kafka vs RocketMQ——多Topic对性能稳定性的影响-转自阿里中间件

    引言 上期我们对比了RocketMQ和Kafka在多Topic场景下,收发消息的对比测试,RocketMQ表现稳定,而Kafka的TPS在64个Topic时可以保持13万,到了128个Topic就跌至 ...

  8. 设置NotePad++设置"不打开上次关闭的文件"

    notepad++是一个很好的记事本工具,但是默认会记录上次打开时未关闭的文件,但是实际上用起来并不方便, 可以按照下面的方式去除,notepad++版本:v6.6.2,os:win7 64位 按照以 ...

  9. java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)

    此错误是由于版本造成的,如果使用mybatis3.4版本以上,配置拦截器规则应增加Intger @Intercepts({ @Signature( type= StatementHandler.cla ...

  10. Pascal 语言中的关键字及保留字

    absolute //指令(变量) abstract //指令(方法) and //运算符(布尔) array //类型 as //运算符(RTTI) asm //语句 assembler //向后兼 ...