Максимальное количество пользовательских подключений

24

В выпуске SQL Server 2012 Standard я знаю, что максимальное количество пользовательских подключений составляет 32 767. Что я должен делать как администратор базы данных, если я направляюсь к этому номеру?

В настоящее время существует 30 000 пользовательских подключений, и ожидается, что это число увеличится.

введите описание изображения здесь

sebeid
источник
5
Если они из приложения, то приложение должно закрыть свое соединение, как только оно будет завершено. Оставление соединения открытым - возможная причина для достижения этого предела
Марк Синкинсон

Ответы:

31

Максимальное количество соединений в разных версиях SQL Server и изданий 32767.

Вы можете определить, сколько подключений в настоящее время имеет 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;

Можно линейно масштабировать количество соединений за пределами 32 767 путем разделения данных между несколькими узлами SQL Server. Однако, по моему мнению, использование шардинга в качестве способа обойти ограничение количества соединений аналогично использованию атомной бомбы для уничтожения паука. Он будет убивать паука, но вы просто могли бы иметь большие проблемы в конце дня. Не говоря уже о том, что создать атомную бомбу чертовски сложно, не говоря уже о том, чтобы правильно использовать шардинг.

Макс Вернон
источник
1
Можете ли вы объяснить, почему мы должны идентифицировать «убиваемые» сеансы с помощью most_recent_sql_handle в соединениях sys.dm_exec_, а не с помощью, скажем, status и last_request_start_time и is_user_process в сеансах sys.dm_exec_ ? Это кажется странным выбором.
Майк Шеррилл "Cat Recall"
Это хороший момент, @Mike - В то время я думал исключительно о соединениях, которые были открыты пулами соединений и которые никогда не использовались. Было бы неплохо добавить is_user_processквалификатор, и, конечно, не мешало бы исключить сеансы, которые имеют last_request_start_timeнесколько недавний характер. Как недавно? Еще один хороший вопрос.
Макс Вернон,
Last_request_start_time, вероятно, должно быть старше, а не новее. Я думаю, что безопасно "убиваемый" пользовательский сеанс был бы тем, который спит и не имел запроса в течение нескольких дней. Я предполагаю, что время отключения зависит от того, насколько хорошо наши прикладные программисты убирают за собой.
Майк Шеррилл 'Cat Recall'
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

Дело об осиротевшей сделке

swasheck
источник