ユーザー接続の最大数


24

SQL Server 2012 Standardエディションでは、ユーザー接続の最大数が32,767であることを知っています。この番号に向かっている場合、DBAとして何をすべきですか?

現在、30,000のユーザー接続があり、この数は増加すると予想されます。

ここに画像の説明を入力してください


5
これらがアプリからのものである場合、アプリは終了後に接続を閉じる必要があります。この制限を打つための可能な理由である接続のオープンを残して
マーク・Sinkinson

回答:


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を使用して接続 sys.dm_exec_ではなく、使用して、言って、ステータスとlast_request_start_timeとis_user_processでセッション?それは奇妙な選択のようです。
マイクシェリル 'キャットリコール'

@Mike-これは良い点です。当時、私は純粋に、接続プーリングによって開かれ、使用されたことのない接続について考えていました。is_user_process修飾子を追加することをお勧めしますlast_request_start_time。また、a がやや最近のセッションを除外しても問題はありません。どれくらい最近ですか?別の良い質問です。
マックスヴァーノン

last_request_start_timeはおそらく新しいものではなく、古いものでなければなりません。安全に「殺せる」ユーザーセッションは、スリープ状態で、数日間リクエストがなかったセッションだと思います。カットオフ時間は、アプリケーションプログラマーが自分自身をクリーンアップする能力に依存していると思います。
マイクシェリル 'キャットリコール'

12

過去に接続プーリングで奇妙な振る舞いに遭遇しましたが、あなたのシナリオはそれらの状況の1つとうまく調和しています。アプリケーションが接続プーリングを使用している場合(そして、この時点で、それを確認または拒否するまではまだ推測です)、多くの接続が開いたままになります。これは仕様です。

接続プーリングは、データベース接続を作成するオーバーヘッドを削減することを目的としています。たとえば、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の接続プーリング

孤立したトランザクションの場合

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.