我正在使用 3 层应用程序 Microsoft Dynamics AX,其中中间层维护与 SQL Server 的连接。几个客户端连接到这个中间层服务器。
中间层服务器通常有几个连接到 SQL Server 的连接,所以我很确定它们正在被池化,但是没有关于如何实现的文档。
通常我们无法将 SPID 与用户或客户端应用程序相关联,但我们可以通过一个选项设置注册表项(特定于 Microsoft Dynamics AX),从而使此信息context_info
在sys.dm_exec_sessions
.
同样,没有关于如何实现的文档。我们掌握的唯一信息是 MSDN 上的一个模糊的博客条目。
帖子提到
添加此信息的性能开销很小。
因此,我们不知道任何实现细节,例如:
- 信息是否以某种方式包含在连接字符串中,还是由 SET CONTEXT_INFO 完成?
- 什么时候重用连接?
- 可以预期的确切影响
有什么方法可以确定服务器端连接池的工作方式以及 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
我可以看到使用了连接池。
首先,
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
几乎必须是在该会话的任何其他查询之前执行的单独的附加查询。类似于以下内容:因此,启用此信息所产生的少量额外开销来自执行此附加查询。
其次,您可以使用 SQL Server Profiler 测试连接池。在“Stored Procedures”类别中选择“RPC:Completed”事件,确保为该事件检查“TextData”、“ClientProcessID”和“SPID”(至少,您可以根据需要选择其他列)。然后,转到“列过滤器”,选择“TextData”,并在“Like”条件中添加以下条件:
exec sp[_]reset[_]connection
. 现在运行该跟踪。如果您看到exec sp_reset_connection实例通过,那是由于使用了连接池。此外,连接池的两个副作用可能会或可能不会出现在 DMV 中,具体取决于请求的连接数。以下查询应捕获池中的许多/大部分连接(请注意,它与 CONTEXT_INFO 无关):
此查询查找正在使用的连接池的以下指示:
SqlCommand
s。沿着类似的思路,也应该可以通过创建一个临时表来测试连接池,每隔几秒
[session_id]
,[connection_id]
从sys.dm_exec_connections
. 然后,只需查找具有相同 connection_id 但不同 session_id 的行。最后,问题中发布的查询对于指示大多数 Web 应用程序的连接池无效。这里的问题是,通常情况下,“program_name”、“login_name”和“host_name”的属性对于 web/app 服务器进行的所有连接都是相同的(因此需要按处理器/按内核许可模型而不是只有 CAL 模型)。
关于连接池,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) 启动重新登录的过程。”