如何找到正在使用我的SQL Server连接池的代码?

时间:2010-07-01 00:27:44

标签: sql-server pool

我根据答案重写了以下内容。

我的网站在数据库服务器上导致高CPU问题,导致服务器不可用。回收应用程序池可以解决问题。根据服务器管理员http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en显示,有些线程处于活动状态大约一个小时。

在我们将Web表单路由添加到应用程序之前,与数据库的交互非常简单并且有效。

在整个应用程序中,它们只包含这样的代码。 是的,这段代码并不完美,但是这个代码不是我们在添加路由之前的问题,没有问题。

  private string GetPublishedParagraphs()
  {
    string query, paragraphs = "";
    try
    {

      m_sql_connection = new SqlConnection(m_base_page.ConnectionString());
      query = "select * from PublishedParagraphs where IDDataContent_page='" + m_IDDataContent_page + "'";

      SqlDataAdapter da = new SqlDataAdapter(query, m_sql_connection);
      DataSet ds = new DataSet();
      da.Fill(ds, "paragraph");

      if (ds.Tables["paragraph"].Rows.Count > 0)
        paragraphs = (string)ds.Tables["paragraph"].Rows[0]["paragraphs"];

      ds.Dispose();
     da.Dispose();
   }
   finally
   {
     m_sql_connection.Close();
   }

   paragraphs = paragraphs.Replace("™", "™");

   return paragraphs;
}

连接字符串如下所示:

server_name; User ID=server_user; Password=server_password

我们仔细检查过每次调用数据库Open()之后都是Close()。 我们在本地运行应用程序时通过查看它们来测量没有打开的连接,并且连接数不会增加:

SELECT SPID,
       STATUS,
       PROGRAM_NAME,
       LOGINAME=RTRIM(LOGINAME),
       HOSTNAME,
       CMD
FROM  MASTER.DBO.SYSPROCESSES
WHERE DB_NAME(DBID) = 'TEST' AND DBID != 0 

(但是,如果我们不关闭连接,则存在泄漏)

我们的应用程序与其工作时的区别在于通过Web表单添加了asp.net路由。这也会调用数据库,但在打开后再次关闭连接。

我们不确定我们还能检查什么。 其他程序员的想法是什么?

ANSWER

我们通过Query Profiler发现了问题。这向我们展示了一个高使用率的查询。将查询追溯回代码显示无限循环一遍又一遍地调用数据库。很难找到,因为循环是由一个机器人调用网站上不再存在的页面发起的。

3 个答案:

答案 0 :(得分:1)

  • 在您显示的代码中,ds和da .Dispose进入finally块。更好的是,使用确保对象处理的using(){}结构

  • 构建自己的字符串作为查询的模式不仅仅是一个巨大的安全漏洞,它也是非常低效的。请改用存储过程和参数。

  • 对进程的查询过于严格。如果您遇到导致连接被拒绝的资源问题,则不会将其限制为单个数据库。关于我唯一要限制的是当前命令 - > spid!= @@ spid

  • 真的需要一些错误消息和上下文 - 它们在哪里可见?告诉我们更多信息,我们可以提供帮助!

祝你好运!


  • 首先,有很多额外的信息!感谢您的跟进。

  • 我建议如果你确定你发布的代码与你从问题中删除它的问题没有任何关系。然而,问题不仅仅是“不完美”的问题。正确处理内存密集型对象 - 初始开发人员认为足够密集以包含dispose()方法 - 与数据库交互的方法 - 当您遇到数据库无法解释的问题时,我认为不是一个小问题

  • 我做了一些谷歌搜索,发现this。虽然我不会说这是问题,但它确实让我思考。当“活动大约一小时的线程”时,是在数据库服务器上还是在Web服务器上进行测量?我不熟悉该工具,但您是否能够从此工具发布日志?

  • 在网络服务器上,您是否能够监控路由代码的操作?路由代码是否以防止无限循环的方式编写/设置 - 请参阅问题和答案here text

  • 在我的答案的早期版本中,我告诉你,只查找特定数据库的@ connections对你的任务来说限制太多了。对您的问题的澄清并不表示您已更正此查询。我建议:


    SELECT 
        is_being_blocked = sp.blocked
        , sp.cpu
        , DB_NAME ( dbid )
        , sp.status
        , LOGINAME=RTRIM(sp.LOGINAME)
        , sp.HOSTNAME
        , sp.Hostprocess
        , sp.CMD
    FROM  SYSPROCESSES sp
    WHERE spid != @@SPID
    ORDER BY 
        sp.blocked ASC
        , sp.cpu DESC

  • 日志 - 在重新启动Web应用程序前10分钟和10分钟后的时间范围内,SQL Server日志的内容是什么?

  • 您是否尝试过,这个问题在开发中是否可重复?

  • 请告诉我们以下声明对您的申请的意义 - 错误消息或其他:“服务器变得不可用”

  • 我强烈建议你使用profiler启动一段sql server。根据你在这个问题中所说的,这就是我将跟踪保存到表(在另一个sql server上)或保存到文件(在另一台机器上而不是sql server框)。此跟踪用于查找严重妨碍生产的问题。这不是你想要定期运行的东西。

我会抓住这些事件

* Errors and Warnings - all of them
* Security Audit 
** Audit Login
** Audit Logout
* Sessions
** Existing Sessions
* TSQL
** SQL: Stmt Starting
** SQL: Stmt Completed
** Prepare SQL
** Exec Prepared SQL

我不会使用除预设之外的任何过滤器。

答案 1 :(得分:1)

您是否尝试在SQL Server Management Studio中运行“sp_who2”查询,以查看代码看起来正常时有多少活动数据库连接。

您可能希望将m_sql_connection变量的范围从类范围更改为成员范围。也许这可能是你的问题?

答案 2 :(得分:0)

你的应用程序池用完了是什么意思?你的意思是连接池吗?

如果您的数据库似乎过度工作,也可能是因为用户可以自由控制m_IDDataContent_page变量。此数据访问代码易受SQL注入攻击。