33

我目前正在对 ASP.net 2.0 应用程序进行一些 GUI 测试。RDBMS 是 SQL Server 2005。主机是 Win Server 2003 / IIS 6.0。

我没有应用程序的源代码,因为它是由没有发布代码的外部公司编写的。

我注意到当我重新启动 IIS 时应用程序运行良好,但经过一些测试,在我打开和关闭浏览器几个小时后,应用程序开始变得越来越慢。我想知道这种行为是否是由于程序员关闭连接的错误做法造成的:我怀疑这里的数据库存在开放连接泄漏。

我猜.Net 垃圾收集器最终会关闭它们,但是......这可能需要一段时间,不是吗?

我有 SQL Server Management Studio,我确实从活动监视器中注意到在数据库上打开了很多连接。

综上所述,这里有一些与主要问题相关的问题:

  1. 在 SQL Server 2005 中有什么方法可以知道连接是因为等待在连接池中使用而打开的,还是因为它们被应用程序使用而打开的?

  2. 有人知道好的在线/纸质资源,我可以在其中学习如何使用性能计数器或其他类型的工具来帮助追踪这类问题吗?

  3. 如果性能计数器是最好的解决方案,我应该注意哪些变量?

4

6 回答 6

63

发现这个线程正在研究类似的问题。我想出了以下 sql 作为调试 SQL Server 中泄漏连接的好方法:

SELECT S.spid, login_time, last_batch, status, hostname, program_name, cmd,
(
      select text from sys.dm_exec_sql_text(S.sql_handle)
) as last_sql
FROM sys.sysprocesses S
where dbid > 0
and DB_NAME(dbid) = '<my_database_name>'
and loginame = '<my_application_login>'
order by last_batch asc

这为您提供的是特定数据库和登录上的所有打开连接,以及在该连接上执行的最后一个 sql,按执行该 sql 的时间排序。

由于连接池,您不能仅仅依靠周围有很多连接的事实来告诉您有连接泄漏,因为连接池将保留连接,即使它们已从代码中正确关闭。然而,如果你确实有连接泄漏,你会看到一些连接被“冻结”——它们会出现在上面的查询中,并且“last_batch”时间戳永远不会改变。其他连接也会挂起,但每次在它们上运行新的 sql 时,“last_batch”时间戳都会更新。所以效果是冻结的连接将浮动到这个查询的顶部。

如果您有相关应用程序的源代码,那么这会为您提供在孤立连接上执行的最后一条 sql,这对于调试非常有价值。

注意'loginame' 的拼写错误(缺少'n')在sys.sysprocesses视图中。上面的说法是正确的。

loginame nchar(128) 登录名。

https://docs.microsoft.com/en-us/sql/relational-databases/system-compatibility-views/sys-sysprocesses-transact-sql?view=sql-server-ver15

于 2012-09-14T16:10:19.750 回答
7

我遇到了这个问题,发现 SQL Server Profiler 是一个很棒的工具,我在短暂的测试运行中监控了该站点,并注意到正在创建的许多连接 (sp_who) 没有被连接池重用,所以我只打开了 SQL Server Profiler 和然后检查从代码中对 SP 的所有调用是否都跟在“sp_reset_connection”调用之后。如果在新批次开始之前呼叫不存在,那么您只是缺少第一个连接。

于 2010-10-28T19:26:57.333 回答
2

您始终可以检查来自 web.config 的连接字符串(主要是如果它们激活了连接池,如果它们启用了任何连接限制)。

此外,如果您使用的是 IIS 6,您可以将 Web 应用程序设置为使用单独的应用程序池,并设置其他选项来回收内存和进程。

关于性能计数器,您可以检查垃圾收集器运行了多长时间、应用程序使用了多少内存等。

如果您有权访问 sql server,则可以监视从应用程序建立的连接(为每个已安装的 SQL Server 实例定义了性能计数器)。

MSDN 杂志上有一些文章。您也可以使用 SOS 调试库附加到应用程序的进程并手动检查它。

而且,如果您没有源代码,请尝试使用Reflector获取应用程序的源代码(它们对于调试非常有用)

@稍后编辑:您也可以在 stackoverflow.com 上查看此问题

于 2008-10-17T15:30:51.313 回答
2

关于( ADO.NET 性能计数器)的 MSDN 参考非常清楚地说明了在分析应用程序时可以查找的内容。您可以使用Windows 内置的perfmon应用程序监视计数器。

除此之外,我建议学习 ADO.NET 连接池。如果您真的怀疑他们的代码中存在错误,您可以使用Red Gate 的 Reflector(现在免费)来查看它,它将 MSIL 反汇编为 C#。

于 2008-10-17T15:34:13.337 回答
1

我会首先查看连接并查看活动时间,看看您是否可以找到保持连接打开的项目。

我想说的是,如果解决方案是重新启动 IIS,您可能还会查看应用程序的内存使用情况,以查看是否存在内存泄漏或确实导致其占用空间增加的东西。

如果打开的连接是一个问题,在活动监视器中,您会看到大量没有活动的连接。

对于性能计数器,您可能会开始查看“SQL Server : General Stats”性能对象。

于 2008-10-17T15:30:23.203 回答
1

Todd Denlinger 编写了一个很棒的类http://www.codeproject.com/KB/database/connectionmonitor.aspx,它监视 Sql Server 连接并报告在一段时间内未正确处理的连接。将其连接到您的站点,它会在发生泄漏时通知您。

于 2011-09-17T02:45:16.777 回答