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. KVO __ 浅谈

    KVO :Key-Value Observing 它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了. ...

  2. 创建Hello World程序(part-1)

    写在前面: 2006年,刚上大学,班上有几个计算机文盲,1分钟打二十几个字都困难,很不幸,我就是其中的一个.强烈的自尊心驱使我不停恶补,翻遍了图书馆的计算机文化基础,知耻而后勇...后来,C语言居然考 ...

  3. DataTable 只保留想要的几列

    using System; using System.Collections; using System.Configuration; using System.Data; using System. ...

  4. UILabel 设置行间距

    UILabel *label1 = [[UILabel alloc]initWithFrame:frame]; label1.numberOfLines = 0; [self.view addSubv ...

  5. ethhdr、ether_header、iphdr、tcphdr、udphdr 结构介绍

    转自:http://blog.csdn.net/petershina/article/details/8573853 ************************eth的结构*********** ...

  6. 转:IT公司的十大内耗,别说你公司没有!

    这篇文章是以前看到的,觉得写得非常好,转载在自己BLOG作为记录.原文:http://www.pmtoo.com/news/2015/0108/7260.html. 当企业发展到一定时期时,会不可避免 ...

  7. 用 IIS 实现请求转发

    最近部门要开发一个简单的APP,部分数据是现有项目已经存在的,为了方便维护,希望只提供一个交互的入口,并且协议的规则不变. 基于这个需求,有两套解决方案: 1.用代码将现有的api封装一层,对请求数据 ...

  8. jquery函数理解与运用

    javascript中有多种不用的方式去理解函数,函数类似于我们以前学过的数学函数,但是在程序设计中,我是按照下面的方式进行理解: 函数的理解: 函数是一个代码块,内容被包含在函数内,通常我们是把一些 ...

  9. getSlotFromBufferLocked: unknown buffer: 0xf3d94ca0

    安卓6.0模拟器导致,换一个模拟器解决

  10. 动态生成一个设定好特殊样式的Tlabel,快速生成代码

    动态生成一个设定好特殊样式的Tlabel,快速生成代码: 1.自己先在可视化界面设定一个Label,像这样: 2.选择label,快捷键ctrl+C 复制,粘贴带代码编辑器去,会生成一段这样的窗体代码 ...