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

时间:2011-10-12 16:59:56

标签: .net sql sql-server sql-server-2008 timeout

我们每天都有一些实例,我们从多个应用程序中获得大量SQL Timeout错误(System.Data.SqlClient.SqlException:Timeout expired。在操作或服务器完成之前经过的超时时间没有回复。)我们的网络上有超过100种不同的应用程序,包括Web和桌面应用程序。从VB6和经典ASP到.NET 4的所有内容。我可以找到显示副作用的各种数据,但无法确定导致这种情况的原因。我们的DBA表示SQL服务器没有任何问题,IT部门表示Web服务器或网络没有任何问题,所以我当然试图解决这个问题。

我真的只是在寻找有关我可以尝试进行其他故障排除的建议,以尝试跟踪此事。

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

这是我到目前为止所做的:

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

如果我想到我们尝试了什么,我会回来再添加更多。请让我知道接下来要解决的问题。

16 个答案:

答案 0 :(得分:24)

  

运行长时间运行的查询和死锁的SQL跟踪。这显示没有   问题发生时的死锁,以及长时间运行的查询   与我们的超时错误一致,但看起来是副作用,并且   不是原因。通常返回的非常基本的查询   立刻最终需要30,60或120秒才能运行。这个   发生了几分钟,然后一切都恢复正常   之后。

看起来有些查询/事务会锁定您的数据库,直到完成为止。您必须找出阻止哪些查询并在其他时间重写/运行它们以避免阻止其他进程。此时等待查询暂停。

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

答案 1 :(得分:12)

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

如果您可以在查询超时时执行sp_who2,则可以使用BlkBy列追溯到持有其他人正在等待的锁定。由于这种情况每天只发生几次,如果您手动运行,可能无法捕获足够的数据,因此我建议您安装一个自动系统来定期转储此输出,或者可能由应用超时异常。您还可以使用活动监视器实时查看查询响应性的降级,如同行建议的那样。

一旦找到长时间运行的查询和执行它的应用程序,您可以通过将该单个应用程序的超时减少到所有其他应用程序之下立即解决超时的多米诺骨牌(现在,它必须更长)。然后,您应该检查代码以确定更好的解决方案。您可以通过在sproc中更快地提交事务来减少锁定的时间,或者使用NOLOCK或UPDLOCK等提示减少读取查询所需的锁定。

以下是关于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

答案 2 :(得分:9)

有点远,但在实验室前一段时间,我们遇到了一个SQL Server似乎没有响应的情况,不是因为我们已经加入了CPU或我们在SQL Server中可以跟踪的任何东西,它似乎对所有测试都可操作但在一些负载下连接失败了。

问题原因是由于针对服务器的流量大意味着我们在Windows中触发了内置的Windows Syn Attack Flood Protection。令人讨厌的是,当你点击这个时,Windows服务器或SQL中没有记录消息 - 你只能看到连接失败的symtpoms - 这是因为windows在接受消息时放慢速度并让我们建立一个队列。从连接的角度来看,服务器似乎没有响应(它甚至不会确认消息到达)

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

向下滚动到SynAttackProtect,您将看到Windows Server 2003 sp1以后的默认设置是默认启用此功能。它实际上是一种DDOS保护机制,并且缺少它触发的日志记录使得在服务器执行此操作时非常难以检测到。

MS实验室花了3天才弄明白。

你提到了100个问题,我们有一个经常连接的应用程序,运行查询然后断开连接,它没有打开连接。这意味着我们在每台机器连接上有多个线程,10台机器,每台机器多个线程,并且认为足够不同的连接被一致地进行/删除以触发防御。

您是否处于该级别(因为它不是MS明确定义的阈值)很难说。

答案 3 :(得分:5)

就像其他海报所建议的那样,听起来你有一个锁争用问题。几个星期前我们遇到了类似的问题;但是,我们的间歇性更强,并且在我们将DBA运行到服务器上以运行sp_who2来追踪问题之前经常被清除。

我们最终做的是在锁定超过某个阈值时实施电子邮件通知。一旦我们实现了这一点,我们就能够识别锁定的进程,并将隔离级别更改为在适当的位置读取未提交以解决问题。

Here's an article that provides an overview of how to configure this type of notification.

如果锁定成为问题,如果您还没有这样做,我建议您查看configuring row versioning-based isolation levels

答案 4 :(得分:2)

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

你必须向后工作一点 - 考虑到你看到超时的表子集,看看这些表上有哪些索引。查找在触摸这些表/索引的时间运行的其他查询。我打赌你会发现一小组更新/插入这样做。

然后你做出一些决定。一种选择是更改超时查询的锁定提示。但这实际上是不好的做法,因为它会在一段时间内掩盖真正的问题。虽然您看到超时会消失一段时间,但根据您选择的提示,您最终可能会出现脏读,然后从这些查询中返回伪造的数据。这可能会比超时更糟糕 - 很难说。

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

答案 5 :(得分:1)

我建议您深入了解超酷的SQL Server Dynamic Management Views功能:

  

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

本文是DMV的一个良好开端,虽然它是为SQL 2005编写的(DMV首次出现):Troubleshooting Performance Problems in SQL Server 2005,尤其是“阻塞”章节。

答案 6 :(得分:1)

我对这些问题的经验(不是在SQL Server上)是过度的多任务通常是问题的原因。如果通过多个连接(几乎)同时查询类似/连接的数据/表,则DBMS可能无法检查所有隔离。这不是磁盘使用的问题,而是使某些连接等待其他连接完成。就CPU使用而言,同步非常昂贵。

在我看来,100个连接太多了。 (根据我的经验),即使是一台机器要求完成的20个连接也可能过于乐观。

答案 7 :(得分:1)

听起来你可能已经有了答案但是如果你需要再看一个地方,你可能想看看你的临时数据库的大小和活动。我们在一个客户端网站上遇到过这样的问题,每天有几次他们的性能会严重降低,偶尔会超时。问题原来是一个单独的应用程序,它正在摧毁临时数据库,因此它影响了整体服务器性能。

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

答案 8 :(得分:1)

如果在SQL服务器上安装了防病毒软件,我发现了类似的问题。 AV的自动更新功能正在为服务器提供时钟,而不允许为SQL Server提供足够的CPU。

另外,您是否在SQL服务器本身上放置了一个小应用程序,用于验证是否可以建立连接或运行非常基本的SQL,如“SELECT GETDATE();”?这将消除网络可能性。

答案 9 :(得分:1)

由于我每天都在进行故障排除,这是我的工作的一部分,这就是我想要做的事情:

  1. 由于它是SQL Server 2008 R2,因此您可以运行作为产品一部分的SQLDiag。您可以在线推荐图书以获取更多详细信息简而言之,捕获服务器端跟踪和阻止程序脚本。

  2. 捕获跟踪后,查找“注意”事件。这将是收到错误的spid。如果按SPID过滤,则会在“注意”之前看到RPC:已完成事件。检查那边的时间。那是30秒吗?如果是,那么客户端等待30秒以从SQL获得响应并且“超时”[这是客户端设置,因为SQL永远不会停止和连接]

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

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

  5. 如果否,则此查询必须等待某些资源(已阻止)

  6. 此时返回阻止程序脚本并查看“注意”来的时间范围

  7. 上面假设问题是SQL Server与网络无关!

答案 10 :(得分:0)

问题是由于查询错误,执行查询的时间超过60秒或表上的锁定

  

问题看起来像正在发生僵局;我们有查询阻止查询及时完成。查询的默认超时是60秒,超过了我们将有超时的SQLException。

     

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

答案 11 :(得分:0)

这些服务器是虚拟化的吗?在另一篇文章中,我读到有关SQL服务器运行有时非常慢,因为内存不足。这反过来是由所谓的内存气球引起的,虚拟器用于限制该虚拟服务器使用的内存量。很难找到,因为物理内存的压力与SQL服务器本身无关。

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

答案 12 :(得分:0)

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

当从SQL Server Management Studio中使用相同的参数精确运行相同的存储过程时,查询将在15秒内运行。但是当使用上面的设置从我们的应用程序运行它时,SqlCommand超时。相同的SqlCommand(具有不同但可比较的数据)已成功运行数周,但现在它失败,任何包含超过20个左右整数的表参数。我们做了一个跟踪并发现当从SqlCommand对象运行时,数据库花费整个90秒获取锁,并且仅在超时时刻调用该过程。我们更改了CommandTimeout时间,无论时间如何,我们选择的存储过程仅在该时段的最后调用。因此我们推测SQL Server无限期地反复获取相同的锁,并且只有Command对象的超时导致SQL Server停止其无限循环并开始执行查询,到那时为时已晚,无法成功。使用类似数据在类似服务器上对该相同过程的模拟没有表现出这样的问题。我们的解决方案是重启整个数据库服务器,之后问题就消失了。

因此,似乎SQL Server中存在一些问题,其中一些资源被累积消耗并且从未被释放。最终,当通过SqlConnection连接并运行涉及表参数的SqlCommand时,SQL Server进入无限循环获取锁。循环由SqlCommand对象的超时终止。解决方案是重新启动,显然是恢复(临时?)理智到SQL Server。

答案 13 :(得分:0)

我们的问题已通过 Windows 团队关闭 TLS-DHE* 密码解决。

我们遇到的问题:我们有从一台服务器(sql server 2012 和 windows 2012 R2)运行并连接到另一台服务器(SQL server 2016 SP2 和 windows 2019)的 SSIS 包,我们曾经有时会超时一些的 SSIS 包,它随机失败。 Windows 团队关闭 TLS-DHE 密码后,问题得到解决。

https://support.microsoft.com/en-us/topic/transport-layer-security-tls-connections-might-fail-or-timeout-when-connecting-or-attempting-a-resumption-326bd5b1-52a1-b367-8179-b154e5c01e90

答案 14 :(得分:-1)

我遇到了类似的问题,发现是由于默认的.Net框架设置

Sqlcommand.Timeout

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

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

它可能是您的web.config或app.config文件中的设置,也可能是您的应用程序/ Web服务器配置文件中的设置。

答案 15 :(得分:-1)

我遇到了同样的问题..我在一些可以识别经常运行很长时间的函数中建立了一些日志记录。当我经常说的时候,我的意思是大约2%的时间。因此,日志的一部分插入了过程或查询的开始时间和结束时间。然后,我生成了一个简单的报告,按总执行时间递减的方式将几天的日志排序。这是我找到的。

长时间运行的实例始终在HH:00和HH:02或HH:30到HH:32之间开始,并且在这些时间之间没有运行任何短期运行的查询。有趣。...

现在看来,我遇到的混乱实际上还有更多的秩序。我使用的恢复目标为0,这在数据库中实现了“间接检查点”,因此我的恢复时间可以达到近1分钟。导致每30分钟创建一次这些检查点。

哇,真是巧合!

在Microsoft的有关更改数据库恢复时间的在线文档中,带有这个小警告...

“为间接检查点配置的数据库上的联机事务处理工作负载可能会导致性能下降。”

哇图...

所以我修改了恢复时间,不再遇到其他问题。