AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 101286
Accepted
Tom V
Tom V
Asked: 2015-05-13 05:28:19 +0800 CST2015-05-13 05:28:19 +0800 CST 2015-05-13 05:28:19 +0800 CST

使用 CONTEXT_INFO 验证连接池服务器端

  • 772

我正在使用 3 层应用程序 Microsoft Dynamics AX,其中中间层维护与 SQL Server 的连接。几个客户端连接到这个中间层服务器。

中间层服务器通常有几个连接到 SQL Server 的连接,所以我很确定它们正在被池化,但是没有关于如何实现的文档。

通常我们无法将 SPID 与用户或客户端应用程序相关联,但我们可以通过一个选项设置注册表项(特定于 Microsoft Dynamics AX),从而使此信息context_info在sys.dm_exec_sessions.

同样,没有关于如何实现的文档。我们掌握的唯一信息是 MSDN 上的一个模糊的博客条目。

帖子提到

添加此信息的性能开销很小。

因此,我们不知道任何实现细节,例如:

  1. 信息是否以某种方式包含在连接字符串中,还是由 SET CONTEXT_INFO 完成?
  2. 什么时候重用连接?
  3. 可以预期的确切影响

有什么方法可以确定服务器端连接池的工作方式以及 context_info 的影响是什么?

更新:从这里
使用这个查询

SELECT des.program_name,
       des.login_name,
       des.host_name,
--       der.database_id,
       COUNT(des.session_id) AS [Connections]
FROM sys.dm_exec_sessions des
INNER JOIN sys.dm_exec_connections DEC
        ON des.session_id = DEC.session_id
WHERE des.is_user_process = 1
--AND des.status <> 'running'
GROUP BY des.program_name,
         des.login_name,
         des.host_name
--         ,der.database_id
HAVING COUNT(des.session_id) > 2
ORDER BY COUNT(des.session_id) DESC

我可以看到使用了连接池。

sql-server connection-pooling
  • 2 2 个回答
  • 1838 Views

2 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-05-13T13:49:01+08:002015-05-13T13:49:01+08:00

    首先,CONTEXT_INFO是会话的属性,而不是连接。当重用同一个会话并执行第一批时,它会被sp_reset_connection重置。似乎在 SQL Server 2000 和可能的早期版本CONTEXT_INFO中没有重置,但从 SQL Server 2005 开始,它肯定会重置为NULL.

    这里的部分混淆是该问题特定于“Microsoft Dynamics AX”,因为一般的 .NET 编程不会有该博客文章中提到的注册表项。此外,Microsoft Dynamics 存储的信息CONTEXT_INFO是其应用程序会话详细信息,这些信息与 SQL Server SPID 无关,并且不能用于推断正在发生连接池,因为应用程序会话自然会跨越多个连接以及 SPID .

    用于设置的机制CONTEXT_INFO几乎必须是在该会话的任何其他查询之前执行的单独的附加查询。类似于以下内容:

    SqlConnection _Connection = new SqlConnection("{connection-string}");
    _Connection.Open();
    
    if(_IsConnectionContextRegistryKeySet)
    {
      SqlCommand _Command = _Connection.CreateCommand();
      _Command.CommandType = CommandType.Text;
    
      _Command.CommandText = @"DECLARE @BinaryInfo VARBINARY(128);
                               SET @BinaryInfo = CONVERT(VARBINARY(128), @StringInfo);
                               SET CONTEXT_INFO @BinaryInfo;";
    
      SqlParameter _ParamInfo = new SqlParameter("@StringInfo", SqlDbType.VarChar, 100);
      _ParamInfo.Value = String.Format("{0} {1} {2}...", AXuserID, AXsessionID, ...);
      _Command.Parameters.Add(_ParamInfo);
    
      _Command.ExecuteNonQuery();
      _Command.Dispose();
    }
    

    因此,启用此信息所产生的少量额外开销来自执行此附加查询。

    其次,您可以使用 SQL Server Profiler 测试连接池。在“Stored Procedures”类别中选择“RPC:Completed”事件,确保为该事件检查“TextData”、“ClientProcessID”和“SPID”(至少,您可以根据需要选择其他列)。然后,转到“列过滤器”,选择“TextData”,并在“Like”条件中添加以下条件:exec sp[_]reset[_]connection. 现在运行该跟踪。如果您看到exec sp_reset_connection实例通过,那是由于使用了连接池。

    此外,连接池的两个副作用可能会或可能不会出现在 DMV 中,具体取决于请求的连接数。以下查询应捕获池中的许多/大部分连接(请注意,它与 CONTEXT_INFO 无关):

    SELECT sssn.login_time,
           DATEDIFF(MILLISECOND, conn.connect_time, sssn.login_time)
                      AS [MillisecondsBetweenConnectionAndSessionStart],
           conn.*
    FROM sys.dm_exec_connections conn
    INNER JOIN sys.dm_exec_sessions sssn
            ON sssn.session_id = conn.session_id
    WHERE conn.session_id <> conn.most_recent_session_id
    OR    DATEDIFF(MILLISECOND, conn.connect_time, sssn.login_time) > 50
    ORDER BY conn.connect_time;
    

    此查询查找正在使用的连接池的以下指示:

    • 当前 session_id 与之前的 session_id 不同。如果这两个 ID 相同,则它可能是也可能不是使用池的连接,因为可以重用相同的 SPID。但是,如果它们不同,那只能是连接池的结果。
    • 建立连接和会话开始之间的时间超过 50 毫秒(尽管该阈值可能因系统而异)。通常在连接后创建的第一个会话在连接后不到 30 毫秒,但它“通常”不应该高于 50,即使执行多个SqlCommands。

    沿着类似的思路,也应该可以通过创建一个临时表来测试连接池,每隔几秒[session_id],[connection_id]从sys.dm_exec_connections. 然后,只需查找具有相同 connection_id 但不同 session_id 的行。

    最后,问题中发布的查询对于指示大多数 Web 应用程序的连接池无效。这里的问题是,通常情况下,“program_name”、“login_name”和“host_name”的属性对于 web/app 服务器进行的所有连接都是相同的(因此需要按处理器/按内核许可模型而不是只有 CAL 模型)。

    • 6
  2. RLF
    2015-05-13T07:09:04+08:002015-05-13T07:09:04+08:00

    关于连接池,Thomas Stringer 发布了:http: //blogs.msdn.com/b/sql_pfe_blog/archive/2013/10/08/connection-pooling-for-the-sql-server-dba.aspx

    要知道的简单事情是:“企业 DBA 需要对这些查询给出的答案是它是特定于提供程序的。换句话说,连接池是在客户端/应用程序端处理的。”

    以二进制形式存储的 CONTEXT_INFO 需要由应用程序设置。CONTEXT_INFO 只是一个小桶,可用于包含有用的信息,例如用户的姓名/ID/登录名。(或者你想在可用的小空间里塞进什么东西。)

    开销很小,但在 CONTEXT_INFO 中插入和提取 BINARY 数据是一个额外的步骤。(但对于在服务帐户下运行的系统很有用,这样您就可以知道当前是谁的连接。)

    感谢 srutzky 澄清池连接已重置,但并未丢弃。至少不是马上。

    Nacho Alonso Portillo 的一篇文章提供了澄清:http: //blogs.msdn.com/b/ialonso/archive/2012/06/04/how-to-determine-whether-a-connection-is-pooled-or-nonpooled .aspx

    它部分说“sp_reset_connection ...执行以下任务:1)清理会话上下文......其中包括......重置CONTEXT_INFO;...... 2)通知他们成功注销的发生...... . 3) 启动重新登录的过程。”

    • 1

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve