如何解决间歇性SQL超时错误

我们每天都有几个实例从多个应用程序中得到一系列SQL超时错误(System.Data.SqlClient.SqlException:超时已过期。在操作完成之前超时时间已到,或者服务器没有响应)我们的networking上有100多种不同的应用程序,包括networking和桌面应用程序。 一切从VB6和经典的ASP到.NET 4.我可以find各种数据,显示副作用,但不能指出是什么原因造成的。 我们的数据库pipe理员说,SQL服务器没有什么问题,IT人员说,networking服务器或networking没有问题,所以当然我还是试图解决这个问题。

我真的只是寻求build议,我可以做什么其他疑难解答,试图跟踪下来。

我们正在集群中运行SQL Server 2008 R2。 有一些不同的服务器连接到它,从Windows Server 2003到2008不同品种。

以下是我迄今为止所做的:

  • 运行长时间运行的查询和死锁的SQL跟踪。 这显示在问题时没有死锁,长时间运行的查询都与我们的超时错误一致,但看起来是副作用,而不是原因。 通常返回的非常基本的查询最终会花费30,60或120秒来运行。 这发生了几分钟,然后一切都恢复正常,然后工作正常。
  • 使用性能监视器来跟踪连接池连接。 这有时会在超时时间附近的连接数量上出现一些尖峰,但仍然没有达到默认的100个连接限制的一半。 再一次,这里似乎没有任何一个原因。
  • 将Web应用程序分离到不同的应用程序池。 我们试图缩小我们认为可能成为主要问题的应用程序(大多数聊天等),并将它们放在单独的应用程序池中,但这似乎不会影响任何内容或帮助我们缩小范围。
  • 监视SQL Server上的磁盘使用情况。 我们已经在SQL服务器上做了一些监控,并且在发生这些超时时没有发现尖峰或任何问题迹象。
  • validation过的TempDB不是问题的原因。

如果我想到我们还试过了什么,我会回来补充更多。 请让我知道接下来要排除故障的一些想法。

运行长时间运行的查询和死锁的SQL跟踪。 这显示在问题时没有死锁,长时间运行的查询都与我们的超时错误一致,但看起来是副作用,而不是原因。 通常返回的非常基本的查询最终会花费30,60或120秒来运行。 这发生了几分钟,然后一切都恢复正常,然后工作正常。

它看起来像一些查询/事务locking你的数据库,直到他们完成。 你必须找出哪些查询被阻塞,并重写它们/在其他时间运行它们以避免阻塞其他进程。 此时等待的查询只是暂停。

需要深入的一点是事务日志和数据库的自动增量大小。 将它们设置为固定大小而不是当前文件的百分比。 如果文件越来越高,分配足够空间的时间最终会随着事务超时而延长。 你的数据库就停下来了。

性能问题归结为CPU,IO或Lock争用。 这听起来像你已经排除了IO。 我猜测CPU不是问题,因为这是一个数据库,而不是一个数字计算器。 所以,这留下了争议。

如果您可以在查询超时时执行sp_who2,则可以使用BlkBy列追踪locking其他人正在等待的locking。 由于这只是每天发生几次,所以如果您手动运行这个数据,可能会遇到足够的数据捕获,所以我build议您设置一个自动化系统来定期转储此输出,或者可能由应用超时例外。 您也可以使用“活动监视器”实时查看查询响应性的下降情况,如同行所示。

一旦find长时间运行的查询和执行该查询的应用程序,就可以通过将该单个应用程序的超时降低到所有其他应用程序的超时(即现在必须更长)来立即解决超时的多米诺骨牌问题。 然后,您应该检查代码以确定更好的解决scheme。 您可以通过在sproc中更早提交事务来减lesslocking的时间,或者使用NOLOCK或UPDLOCK等提示来减less读取查询所需的locking。

这里有更多关于sp_who2的阅读: http ://sqlserverplanet.com/dba/using-sp_who2/

和查询提示: http : //msdn.microsoft.com/en-us/library/ms181714.aspx http://msdn.microsoft.com/en-us/library/ms187373.aspx

一点点,但在实验室的一段时间,我们有一个情况,一个SQL服务器似乎没有响应,而不是因为我们钉了CPU或任何我们可以跟踪在SQL Server中,它似乎对所有testing都可用,但连接失败在一些负载下。

这个问题原来是由于对服务器的stream量大,这意味着我们正在触发Windows内的Syn Attack Flood Protection。 令人讨厌的是,当你打这个时,在windows服务器或SQL内没有logging的消息 – 你只能看到连接失败的symtpoms – 这是因为接受消息时窗口变慢,让我们build立一个队列。 从连接的angular度来看,服务器似乎没有反应,它应该(它甚至不承认消息到达)

http://msdn.microsoft.com/en-us/library/ee377084(v=bts.10).aspx

向下滚动到SynAttackProtect,你将会看到windows server 2003 SP1以后默认启用这个function。 这是一个有效的DDOS保护机制,而且它所触发的日志logging不足使得检测服务器何时执行此操作非常困难。

在实验室里花了3天时间才找出来的。

您提到了100个连接,我们有一个不断连接的应用程序,运行查询,然后断开连接,但没有打开连接。 这意味着我们在每台机器连接上都有多个线程,10台机器,每台机器上有多个线程,并且被认为足够不同的连接被持续/断开以触发防御。

不pipe你是在那个级别(因为它不是一个MS明确定义的门槛)很难说。

就像其他海报所build议的,这听起来像是你有一个锁争用问题。 几周前我们遇到了类似的问题, 然而,我们的时间更为间歇,而且在我们能够将DBA运行到服务器上来运行sp_who2来查明问题之前,经常会被清理干净。

我们最终做的是如果一个锁超过​​了一定的阈值,就实现一个电子邮件通知。 一旦我们完成了这个工作,我们就能够识别被locking的进程,并且在适当的时候将隔离级别改为未提交的来解决问题。

这里有一篇文章概述了如何configuration这种types的通知。

如果locking是问题的原因,如果你还没有这样做,我会build议寻找configuration行版本化的隔离级别 。

您的追踪和分析正处于正确的轨道上。 你需要做的是寻找超时查询的共同点 – 它们很可能都会碰到一小部分表或索引。 我怀疑有些应用程序有一个长期运行的更新/插入,影响使用受更新/插入影响的索引的表上的查询。

你必须稍微往后退一点 – 考虑到你看到的表的子集,看看那些表上有什么索引。 查找其他正在运行的查询,触及这些表/索引。 我打赌你会发现一小组更新/插入这样做。

那么你有一些决定。 一种select是更改正在超时的查询的locking提示。 但是这是一个非常糟糕的做法,因为它会掩盖真正的问题一段时间。 当你看到超时时间会消失一段时间,根据你select的提示,最后可能会有脏读,然后从这些查询返回假数据。 这可能会比超时更糟 – 很难说。

最好的办法是找出哪些应用程序正在提交您find的更新/插入内容,并深入了解为什么需要这么长时间。

我build议你深入了解超酷的SQL Server的dynamicpipe理视图function:

dynamicpipe理视图和函数返回可用于监视服务器实例运行状况,诊断问题并调整性能的服务器状态信息。

本文是DMV的一个很好的开始,虽然它是为SQL 2005编写的(DMVfunction首次出现): SQL Server 2005中的性能问题疑难解答 ,尤其是“阻塞”章节。

听起来像你可能已经有你的答案,但万一你需要一个地方看看你可能想看看你的临时数据库的大小和活动。 我们曾经在一个客户端有过这样的问题,一天他们的performance会恶化,偶尔会超时。 问题原来是一个单独的应用程序,它颠簸了临时数据库,影响了整体服务器的性能。

祝你好运,继续排除故障!

我发现如果在SQL服务器上安装了防病毒软件,就会发生类似的问题。 AV的自动更新function是为服务器提供时钟,并且没有为SQL Server提供足够的CPU。

另外,你是否在SQL服务器本身上放置了一个小应用程序,validation是否可以build立连接,或者像“SELECT GETDATE();”那样运行非常基本的SQL? 这将消除networking的可能性。

由于我每天都会做一些工作,所以我想这样做:

  1. 由于它是SQL Server 2008 R2,所以可以运行作为产品一部分的SQLDiag。 您可以在网上参考书籍了解更多详情。 简而言之,捕获服务器端跟踪和阻止程序脚本。

  2. 一旦捕获到踪迹,寻找“注意”事件。 这将是接收到错误的spid。 如果按SPID筛选,则会在“注意”之前看到RPC:Completed事件。 检查那边的时间。 那是30秒吗? 如果是的话,那么客户端等了30秒才能得到SQL响应,并得到“超时”[这是客户端设置,因为SQL永远不会停止和连接]

  3. 现在检查一下正在运行的查询是否需要30秒?

  4. 如果是,则调整查询或增加客户端的超时设置。

  5. 如果不是,那么这个查询必须等待一些资源(阻塞)

  6. 此时返回Blocker Script并检查“注意”出现的时间

以上是假设问题与SQL Server没有networking相关!

我对这些问题的经验(不是在SQL Server上)是过多的多任务往往是问题的原因。 如果通过多个连接在(几乎)同时查询到类似/连接的数据/表,那么DBMS在检查所有隔离时可能会遇到困难。 这不是一个磁盘使用问题,而是让一些连接等待其他事情的完成。 就CPU使用情况而言,同步是非常昂贵的。

我认为这100个连接太多了。 (以我的经验再次)甚至有20台连接要求通过一台机器完成可能过于乐观。

这个问题是因为一个错误的查询执行查询的时间超过60秒或者表上的一个Lock

这个问题看起来像是陷入僵局。 我们有阻止查询完成的查询。 查询的默认超时时间为60秒,超出此范围时,将出现超时的SQLException。

请检查SQL Server日志中是否存在死锁。 另一种解决问题的方法是增加命令对象的超时(Temp Solution)。

这些服务器是虚拟化的吗? 在另一篇文章中,我读到了一个SQL服务器,由于缺乏足够的内存,有时运行速度非常缓慢。 这又是由虚拟器用于限制虚拟服务器使用的内存量的所谓内存膨胀引起的。 这很难find,因为物理内存的压力与SQL服务器本身无关。

临时性能降低的另一个常见原因可能是病毒扫描程序。 当安装新的病毒定义时,所有其他进程将受到影响,运行速度非常慢。 检查出任何其他自动更新过程,这可能也意外地占用了很多资源。 祝你好运!

我们在SQL Server 2012 / SP3中通过C#应用程序中的SqlCommand对象运行查询时遇到过这种情况。 Command是一个具有一个表参数的存储过程的简单调用; 我们通过了大约300个整数的列表。 该过程依次调用三个用户定义的函数,并将该表作为parameter passing给每个函数。 CommandTimeout被设置为90秒。

当从SQL Server Management Studio中使用相同的参数运行完全相同的存储过程时,查询在15秒内运行。 但是,当使用上述设置从我们的应用程序运行时,SqlCommand超时。 相同的SqlCommand(具有不同但可比较的数据)已经成功运行了数周,但现在失败了包含20多个整数的任何表参数。 我们做了一个跟踪,发现从SqlCommand对象运行时,数据库花费了整整90秒的时间来获取锁,并且只会在超时时刻调用该过程。 我们改变了CommandTimeout的时间,不pipe什么时候我们select的存储过程只会在那段时间的最后被调用。 因此,我们推测SQL Server无限期地一次又一次地获取相同的锁,并且只有Command对象的超时导致SQL Server停止其无限循环并开始执行查询,到那时为时已晚。 在使用类似数据的类似服务器上对相同过程的仿真没有performance出这样的问题。 我们的解决scheme是重新启动整个数据库服务器,然后问题消失。

所以看起来在SQL Server中存在一些问题,其中一些资源被累积消耗并且从未被释放。 最后,当通过SqlConnection连接并运行涉及表参数的SqlCommand时,SQL Server会进入无限循环获取锁。 循环由SqlCommand对象的超时终止。 解决scheme是重新启动,显然恢复(临时?)到SQL Server的完整性。

我有一个类似的问题,发现是由于默认的.net框架设置

Sqlcommand.Timeout

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout(v=VS.100).aspx

默认情况下,Microsoft在上面的URL中设置为30秒,请尝试在打开连接之前将其设置为更高的秒数或-1,以查看是否可以解决问题。

这可能是您的web.config或app.config文件或您的应用程序/ Web服务器configuration文件的设置。