最大用户连接数


24

在SQL Server 2012 Standard Edition中,我知道用户连接的最大数量为32,767。如果我朝着这个数字前进,我应该怎么做?

当前有30,000个用户连接,并且这个数字有望增加。

在此处输入图片说明


5
如果这些来自应用程序,则应用程序应在完成后关闭其连接。断开连接可能是达到此限制的原因
Mark Sinkinson

Answers:


31

SQL Server版本之间最大连接数为32,767。

您可以通过查看以下内容确定SQL Server当前具有的连接数:

SELECT ConnectionStatus = CASE WHEN dec.most_recent_sql_handle = 0x0 
        THEN 'Unused' 
        ELSE 'Used' 
        END
    , CASE WHEN des.status = 'Sleeping' 
        THEN 'sleeping' 
        ELSE 'Not Sleeping' 
        END
    , ConnectionCount = COUNT(1)
FROM sys.dm_exec_connections dec
    INNER JOIN sys.dm_exec_sessions des ON dec.session_id = des.session_id
GROUP BY CASE WHEN des.status = 'Sleeping' 
        THEN 'sleeping' 
        ELSE 'Not Sleeping' 
        END
    , CASE WHEN dec.most_recent_sql_handle = 0x0 
        THEN 'Unused' 
        ELSE 'Used' 
        END;

如果要考虑上述查询中已使用和未使用的连接之间的比率,则很可能连接到服务器的客户端应用程序启用了连接池,并且这些连接没有得到有效利用。您可能希望开发人员修改这些应用程序的连接字符串,以限制连接池的大小,并确保它们正确处理了连接。如果未正确处理连接,则只要客户端应用程序正在运行,它们就会保持打开状态。

如果您感到特别狂躁,并且需要摆脱最近没有执行任何操作的所有连接(无论它们当前是否正在执行工作),则可以运行以下代码,这将生成会话列表,可以被杀死 您需要将生成的命令复制并粘贴到新的SSMS窗口中,以实际运行命令。我还建议您更新简历,以防万一

DECLARE @cmd NVARCHAR(MAX);
SET @cmd = '';
SELECT @cmd = @cmd + 
    CASE WHEN @cmd = '' THEN '' ELSE CHAR(13) + CHAR(10) END 
    + 'KILL ' + CONVERT(VARCHAR(MAX), dec.session_id) + ';'
FROM sys.dm_exec_connections dec
WHERE dec.most_recent_sql_handle = 0x0;

PRINT @cmd;

通过在多个SQL Server节点之间分片数据,可以线性地将连接数线性扩展到32,767以上。但是,在我看来,使用分片来绕开连接数量限制的方法类似于使用原子弹杀死蜘蛛。它杀死蜘蛛,但最终您可能会遇到更大的问题。更不用说制造原子弹相当困难,更不用说正确实施工具分片了。


1
你能解释为什么我们应该找出“killable” 会议通过使用sys.dm_exec_ most_recent_sql_handle 连接,而不是使用,比如说,状态和last_request_start_time和is_user_process在sys.dm_exec_ 会议?这似乎是一个奇怪的选择。
Mike Sherrill'Cat Recall'17

@Mike,这是个好点-当时我纯粹是在考虑连接池已打开但从未使用过的连接。添加is_user_process限定符是一个好主意,当然排除不包含last_request_start_time最近的会话也不会受到损害。最近多久?另一个好问题。
Max Vernon

last_request_start_time应该较旧而不是较新。我认为一个安全的“可杀死”用户会话将是正在休眠并且几天没有请求的会话。我猜截止时间取决于我们的应用程序员在清理自己之后的能力。
Mike Sherrill'Cat Recall'17

12

过去,我在连接池方面遇到了奇怪的行为,您的情况与其中一种情况非常吻合。如果您的应用程序正在使用连接池(目前仍在推测,直到您确认或拒绝),然后您将有许多连接保持打开状态。这是设计使然。

连接池旨在减少创建数据库连接的开销。让我们以一个3的连接池为例,据我所知,生命周期是这样的(从一个冷的连接池缓存开始):

  1. 应用程序用户A要求连接到数据库
  2. 连接池启动到数据库的连接线程1
  3. 应用程序用户B请求与数据库的连接
  4. 连接池启动到数据库的连接线程2
  5. 应用程序用户A关闭与连接池的连接...
  6. 应用程序用户C请求与数据库的连接
  7. sp_reset_connection线程1上的连接池问题
  8. 连接池将线程1分配给应用程序用户C

这过于简单了,但是要点包括:

  • 连接将在连接池线程池之间保持打开状态和数据库直到数据库或连接池强行关闭连接为止
  • 在最后一个会话执行上下文中,连接保持打开状态,直到该线程被另一个用户重用为止,此时sp_reset_connection将调用该线程。

这是我用来得出这些结论的参考资料。

SQL Server DBA的连接池

孤单交易案

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.