【问题标题】:Help troubleshooting SqlException: Timeout expired on connection, in a non-load situation帮助排除 SqlException: Timeout expired on connection, in a non-load 情况
【发布时间】:2010-11-28 03:54:56
【问题描述】:

我有一台服务器托管我的网站,该网站的流量几乎为零。
每天都有一些人(

几乎每天晚上,RSS 阅读器都会在半夜打到我们,并得到一个异常,即网站由于连接超时而无法连接到 SQL Server。 细节非常奇怪,所以我正在寻找可能是什么问题的帮助,因为我不知道从哪里开始寻找了。

我们在 Windows Server 2008 上使用 ASP.Net MVC、Entity Framework 和 SQL Server 2008。这台机器是我们从不完全是顶级供应商那里获得的专用机器,因此可能配置不理想,或者谁知道还有什么。
盒子也很小,只有 1Gb 的 RAM,但它应该能承受我们现在的负载......

我正在复制下面的完整调用堆栈,但首先,我们知道一些事情:

  • 当 iTunes 查询我们的站点时,总是会发生该错误。我相信这应该与任何事情无关,但事实是我们只能从 iTunes 获得它。我最好的猜测是,发生这种情况是因为只有 iTunes 会在晚上没有其他人打我们的时候查询我们。
  • 我们的一个理论是 SQL Server 和 IIS 正在争夺内存,其中一个因不使用而被分页到磁盘,当有人“唤醒它”时,读取所有内容需要很长时间从磁盘回到内存。这是可能发生的事情吗? (我有点放弃这个,因为如果可能的话,这听起来像是 SQL Server 中的设计问题)
  • 我还考虑过我们泄漏连接的可能性,因为我们可能没有适当地处理 EF 实体 (see my question here)。这是我通过谷歌搜索问题唯一能找到的。考虑到我们的负载极低,我将放弃它。
  • 这总是在晚上发生,所以这很可能与一段时间内没有发生任何事情有关。例如,我很确定当这些请求命中时,Web 服务器进程被回收并且它正在启动/重新 JIT 处理所有内容。不过,重新 JITting 并不能解释 SQL 超时。

更新:我们按照建议附加了一个分析器,但我们花了很长时间才发现一个新的异常。这是我们知道的新东西:

  • 附加分析器大大减少了我们得到的错误数量。事实上,在正常情况下每天获得几个之后,我们不得不等待 3 或 4 天才能发生一次。一旦我们停止分析器,它就会回到正常的错误频率(甚至更糟)。所以探查器有一些效果,在一定程度上隐藏了这个问题,但不是完全隐藏。
  • 查看 IIS 请求日志旁边的分析器跟踪,请求和查询之间存在预期的 1-1 对应关系。但是,时不时地,我会看到很多正在执行的查询与 IIS 日志完全没有关联。事实上,在记录实际错误之前,我在 3 分钟内收到了 750 个查询,所有这些都与 IIS 日志完全无关。查询文本看起来像 EF 生成的那种不可读的废话,它们并不完全相同,它们看起来都像来自网站的查询:相同的应用程序名称、用户等。让我们知道这有多荒谬也就是说,该站点在 2 天 的过程中收到了大约 370 个 IIS 请求访问数据库
  • 这些无法解释的查询并非来自与之前网站查询相同的 ClientProcessID,尽管如果进程在此期间被回收,它们可能仍然来自网站。在最后一个解释的查询和第一个无法解释的查询之间几乎有一个小时没有活动。
  • 其中一个我不知道它们来自哪里的长连串查询正好在我记录错误之前出现,所以我相信这是我们应该遵循的线索。
  • 正如我最初预期的那样,当执行引发错误的查询时,它来自与前一个不同的 ClientProcessID,(比上一个无法解释的晚 8 分钟,比上一个 IIS 晚几乎一小时)。这意味着,对我来说,工作进程确实被回收了。
  • 这是我完全不明白的。 IIS 日志显示,在错误请求前一分钟,有 4 个得到了完美的服务,尽管这些查询根本没有显示在跟踪中。事实上,在这 4 个进展顺利之后,我连续快速抛出了 4 个异常,这 4 个也没有出现在跟踪中(这是有道理的,因为如果连接中有超时,则查询应该永远不会被执行,但我也没有在跟踪中看到连接尝试)

所以,简而言之,我对此一无所知。我找不到那些快速连续运行的数百个查询的原因,但我相信这些肯定与问题有关。
我也不知道如何诊断连接问题...
或者 Profiler 跟踪如何可能会丢失一些根据 IIS 正常执行的查询...

有什么想法吗?


这是异常信息:

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
   --- End of inner exception stack trace ---
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
   at System.Data.EntityClient.EntityConnection.Open()
   at System.Data.Objects.ObjectContext.EnsureConnection()
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
   at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   at MyProject.Controllers.SitesController.Feed(Int32 id) in C:\...\Controller.cs:line 38
   at lambda_method(ExecutionScope , ControllerBase , Object[] )
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

我们将不胜感激任何想法。

【问题讨论】:

  • 我们遇到了同样的问题,内存应该不是问题......我们在 SQL Server 上有 40 个演出,而 IIS 在另一个盒子上。这是否以任何方式解决?
  • 什么“同样的问题”?!?!丹尼尔斯的问题、我的回答以及他对我的回答的 cmets 中有很多详细的信息。如果你的情况完全符合所有这些描述的每一个细节,那将是非常不同寻常的......
  • 奇怪,我从 Azure SQL Server 收到错误,这不应该受到任何资源(RAM、CPU)不足的影响,如果是本地机器(其他主机服务),建议这样做。跨度>

标签: sql-server-2008 timeout connection connection-timeout


【解决方案1】:

内存不足

这很可能是内存问题,可能是由其他事情加重或触发的,但本质上仍然是内存问题。还有其他两种(不太可能)的可能性,您应该首先检查并消除(因为这样做很容易):

容易检查的可能性:

  1. 您可能启用了“自动关闭”:“自动关闭”可以完全具有这种行为,但很少会启用它。要检查这一点,请在 SSMS 中右键单击您的应用程序数据库,选择“属性”,然后选择“选项”窗格。查看“自动关闭”条目并确保将其设置为 False。还要检查 tempdb。

  2. SQL 代理作业可能会导致此问题:检查代理的历史日志以查看在事件期间是否有任何作业持续运行。记住也要检查维护作业,因为像重建索引这样的事情在运行时经常被认为是性能问题。这些现在不太可能成为候选对象,只是因为它们通常不会受到 Profiler 的影响。

为什么看起来像内存问题:

如果这些没有显示任何内容,那么您应该检查内存问题。我怀疑内存是你案件的原因,因为:

  • 您有 1 GB 的内存:虽然这在技术上高于 SQL Server 的最低要求,但远低于 SQL Server 的推荐值,并且远低于我的经验对于生产来说是可以接受的,即使是轻微的加载服务器。

  • 您在同一个机器上运行 IIS 和 SQL Server:这本身不推荐,很大程度上是因为会导致内存争用,但只有 1 GB 的内存会导致 IIS,应用程序、SQL Server、操作系统和任何其他任务和/或维护都在争夺非常少的内存。 Windows 管理这一点的方式是通过积极地将内存从非活动进程中取出来为活动进程提供内存。在这种情况下,像 SQL Server 这样的大型进程可能需要数秒甚至数分钟才能取回足够的内存以完全处理请求。

  • Profiler 解决了 90% 的问题:这是一个重要线索,表明内存可能是问题所在,因为通常情况下,像 Profiler 这样的东西对这个特定问题有这种影响:Profiler 任务保留 SQL Server只是一点一直活跃。通常,这足以将其排除在操作系统的“清道夫”列表之外,或者至少在一定程度上减少它的影响。

如何检查内存是否是罪魁祸首:

  1. 关闭 Profiler:它对问题有海森堡效应,因此您必须将其关闭,否则您将无法可靠地看到问题。

  2. 从另一个机器运行系统监视器 (perfmon.exe),远程连接到运行 SQL Server 和 IIS 的机器上的性能收集服务。您可以最轻松地做到这一点,首先删除三个默认统计信息(它们仅是本地的),然后添加所需的统计信息(如下),但请确保在第一个下拉列表中更改计算机名称以连接到您的 SQL盒子。

  3. 通过在 perfmon 上创建“计数器日志”将收集的数据发送到文件。如果您对此不熟悉,那么最简单的做法可能是将数据收集到一个制表符或逗号分隔的文件中,您可以使用 Excel 打开该文件进行分析。

  4. 设置您的 perfmon 以收集到一个文件并向其中添加以下计数器:

    -- 处理器\%处理器时间[总]

    -- PhysicalDisk\% 空闲时间[每个磁盘]

    -- 物理磁盘\平均。磁盘队列长度[每个磁盘]

    -- 内存\页数/秒

    -- 内存\页面读取/秒

    -- 内存\可用 MBytes

    -- Network Interface\Bytes Total/sec[对于每个正在使用的接口]

    -- 进程\% 处理器时间[见下文]

    -- Process\Page Faults/sec[见下文]

    -- 流程\工作集 [见下文]

  5. 对于进程计数器(上图),您希望包括 sqlserver.exe 进程、任何 IIS 进程和任何稳定的应用程序进程。请注意,这仅适用于“稳定”流程。根据需要不断重新创建的流程无法以这种方式捕获,因为无法在它们存在之前对其进行指定。

  6. 在问题最常发生的时间将此集合运行到文件中。将收集间隔设置为接近 10-15 秒。 (这会收集大量数据,但您将需要此分辨率来挑选单独的事件)。

  7. 发生一个或多个事件后,停止收集,然后使用 Excel 打开收集的数据文件。您可能必须重新格式化时间戳列,使其可见并显示小时、分钟和秒。使用您的 IIS 日志查找事件的确切时间,然后查看性能数据以了解事件之前和之后发生的情况。特别是你想看看它的工作集之前是否很小,之后是否很大,中间有很多页面错误。这是这个问题最明显的迹象。

解决方案:

要么将 IIS 和 SQL Server 分开到两个不同的盒子上(首选),要么给盒子添加更多内存。我认为至少 3-4 GB。

那些奇怪的 EF 东西怎么样?

这里的问题是,它很可能是外围问题或仅对您的主要问题有贡献。请记住,Profiler 使您 90% 的事件消失了,所以剩下的,可能是一个不同的问题,或者它可能只是问题的最极端的加重。由于它的行为,我猜它要么循环缓存,要么对应用程序服务器进程进行其他一些后台维护。

【讨论】:

  • 感谢您的全面回答!让我们看看...自动关闭已关闭。唯一的代理工作是备份,我们所有的错误都在备份时间之外。内存:系统报告内存使用量为 807Mb,尽管您所说的确实很有意义,并且与我们看到的其他内容相关。我只是在不同的服务器中设置了一个 cron 来每分钟发出一个 Web 请求,从那时起我就没有出现任何错误......我的口味已经过去了足够多的日子,但它看起来很有希望......这支持SQL Server 被发送到磁盘的理论。
  • 至于奇怪的 EF 东西......它最终成为该服务器中的第二个网站,其负载甚至低于我遇到此问题的一个网站,这是非常糟糕的编码,并最终为每个页面加载向数据库抛出数百个查询。我们已禁用该应用程序,错误报告的频率似乎有所降低,但我们仍然有它们。内存不再占用内存的事实可能是减少的原因,我猜
  • 真正让我沮丧的是,我有一个 W2003 机器,只有 1gb 的 ram 运行许多 web 应用程序,加上 sql server 等,它多年来一直运行良好(它真的值得升级),虽然这个盒子只有这个非常轻的负载,非常小的网站,有一个很小的数据库,而且它显然正因为它而死去......如果这真的是问题的原因,那么 W2008 和 SQL2008 是一个巨大的内存猪,比较到旧版本...
  • 是的,从安装 SQL Server 2000 的角度来看,SQL Server 2005 和 2008 需要 大量 内存。但是,从现代服务器和硬件的角度来看,1GB 的内存确实不是很多。哎呀,仅操作系统就喜欢拥有大约 500MB 或更多。仅我的笔记本电脑就有 2GB,我真的希望我有更多。
  • 我们通过 EF 执行 proc 得到了这个,我在服务器上验证了这种情况肯定是内存问题。
【解决方案2】:

我会将超时的时间戳与您每晚备份的执行时间进行比较。如果它们一致,您可以将您的 RSS 提要设置为当时的静态。

要尝试的另一件事(即使它不完全是答案)是在遇到超时异常时立即运行sp_who。它不会捕获所有内容(有问题的过程可能会在您运行此程序时完成),但您可能会很幸运。

您还可以在晚上回家时启动 SQL Profiler,如果您再次看到错误,则在第二天早上逐步完成活动。请确保不要从服务器本身运行它(我很确定它会在启动时提醒您这一点)。

编辑:处理您的更新。

EF 是否更新/创建其缓存?它可以一次解释大量查询,以及为什么以后没有查询有数据库命中。

除此之外,您似乎有一只黑森虫。我能想到的唯一要添加的是更多的日志记录(到文件或事件日志)。

【讨论】:

  • 感谢您的想法,但似乎并非如此。我们的备份在上午 8 点运行,并且在那个时间左右没有发生这些错误。此外,我们的数据库非常小(.bak 文件为 2Mb),所以我怀疑这可能需要很长时间才能运行......
  • 是您在早上 8 点运行的系统备份还是您的 SQL Server 备份?这些通常是在不同时间运行的不同工具和/或进程(尽管一些备份产品可以让您同步拖链,但它们在不同时间仍然是不同的步骤)。
【解决方案3】:

它闻到了同时运行的 cronned 东西。 正如 RBarryYoung 所说.. 一些夜间备份或者它可能是别的东西 您对服务器有 root 访问权限吗? 你能看到 crontab 吗?

可能是 SQL 服务器上的某个全文索引插件在您遇到问题时运行其重新索引过程?

【讨论】:

  • 并非如此,随着时间的推移,它开始越来越频繁地发生在一天中的不同时间。我确实具有对服务器的 root 访问权限。它是 Windows 的,所以没有“crontabs”,但“计划任务”里面什么都没有。
【解决方案4】:

就我而言,当我安装 sqlserver 2008 r2 sp3 时,问题就消失了。

服务器:Windows 7+SqlServer 2008 R2(开发版) 客户端:Raspberrypi 3B+,Asp.net Core+EF Core

【讨论】:

    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    相关资源
    最近更新 更多