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的端口,本示例中,端口为143349428
 
在这里需要额外讲解一下,当客户端程序创建连接到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. Android基础学习第三篇—Intent的用法

    写在前面的话: 1. 最近在自学Android,也是边看书边写一些Demo,由于知识点越来越多,脑子越来越记不清楚,所以打算写成读书笔记,供以后查看,也算是把自己学到所理解的东西写出来,献丑,如有不对 ...

  2. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备一)

    上节中提到在遍历创建控件树后,执行了以下操作:      1. CDialogBuilder构建各控件对象并形成控件树,并返回第一个控件对象pRoot:     2. m_pm.AttachDialo ...

  3. 创建Unity3D的MacOS Plugin的正确姿势

    http://www.tedlindstrom.se/how-to-link-dylibs-into-unity3d/ I was roaming around the net looking for ...

  4. artTemplate-master的应用

    刚开始,在没有使用这个模板之前,一致都是后台返回一个json的字符串,来在前端自己拼接字符串,不但麻烦,而且费时费力,而且还有时候经常拼接错误!导致了工作效率的延长 js模板的使用 <scrip ...

  5. 注解 @RequestParam,@RequestHeader,@CookieValue,Pojo,servlet原生API

    1.@RequestParam 我们的超链接:<a href="springMvc/testRequestParam">testRequestParam</a&g ...

  6. nodejs复习01

    console 格式化 console.log("%s:%s", "a", "b") //字符串 console.log("%d. ...

  7. 支付宝支付-APP支付服务端详解

    支付宝APP支付服务端详解 前面接了微信支付,相比微信支付,支付宝APP支付提供了支付分装类,下面将实现支付宝APP支付.订单查询.支付结果异步通知.APP支付申请参数说明,以及服务端返回APP端发起 ...

  8. Angular内置指令(一)

    要注意的是不要把自己开发的指令以ng开头,以免与内置指令冲突  目录:ng-disabled,ng-readonly,ng-checked,ng-selected,ng-href,ng-src,ng- ...

  9. Yii框架CURD方法

    在YII框架中,CURD有2种方式: 1.AR模式:2. DAO模式 AR模式下 查全部   MODEL  $model->find()->asArray()->all()查单 个  ...

  10. HDU 1907 Nim博弈变形

    1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形. ...