web-dev-qa-db-ja.com

ログインなしのユーザー接続

SQL Serverのパフォーマンスを見ていて、接続数が多くなるとCPU使用率が高くなることに気づきました(これは正常であると思います)。通常、平均接続数は約120でしたが、過去1週間からの接続数は平均は200以上になり、時には400以上になることもあります。これにより、CPU使用率が高くなり、続いてメモリプレッシャーが発生し始め、プランキャッシュがフラッシュされます(長期的な解決策としてLPIMをオンにする必要がある場合があります)。

これはパフォーマンスの問題を引き起こしています。だから私はデータベースの開いているセッションをチェックし、以下は結果です:

enter image description here

これらの70の接続/セッションは、ネットワーク経由でアプリケーションにアクセスする実際のユーザーからのものです。 SSRSからの接続はほとんどなく、最後の4セットの接続は、開発者/ DBAからのリモートデスクトップ接続です。

これらの120の接続が何であるかはわかりません。これらの接続にはLoginNameさえありません。

Sys.dm_exec_sessionから詳細をキャプチャしました。どうやら、ログイン名のないセッションは何もしません。 0 CPU時間、0論理読み取りなどを使用します。

enter image description here

他にどこを見ればいいのかわかりません。

Sidのsys.sysloginsからの結果。ログインは、実際のユーザーからのログインと同じです。 enter image description here

70の接続は、.Netアプリケーションの汎用SQLログインを使用しています。ログイン名のない他の120の接続は同じSIDを持っています。

ユーザーがアプリケーションにログインして別のモジュールに切り替えた後、同じモジュールに戻って重複セッションが作成され、実際のセッションが開いたままになっている場合に発生しますか?

これはの結果です

  SELECT con.*, '--' AS [---], ses.*, '--' AS [---], req.* 
  FROM sys.dm_exec_connections con 
  INNER JOIN sys.dm_exec_sessions ses ON con.[session_id] = ses.[session_id] 
  LEFT JOIN sys.dm_exec_requests req ON req.[session_id] = con.[session_id] WHERE ses.[login_name] = N''

enter image description here

enter image description here

最後に、ログイン名のないそれらのセッションが何をしているかを見つけました。彼らは、メインのクエリ/ストアドプロシージャから呼び出される関数を実行しています。

これが私が使ったクエリです。

SELECT 
  con.connection_id,ses.status,ses.Host_name,ses.Host_process_id,ses.program_name,ses.last_request_start_time,ses.last_request_end_time,req.status,req.command,
  Substring(st.TEXT,(req.statement_start_offset / 2) + 1, ((CASE req.statement_end_offset WHEN -1 THEN Datalength(st.TEXT) ELSE req.statement_end_offset END - req.statement_start_offset) / 2) + 1) AS statement_text

  FROM sys.dm_exec_connections con 
  INNER JOIN sys.dm_exec_sessions ses ON con.[session_id] = ses.[session_id] 
  LEFT JOIN sys.dm_exec_requests req ON req.[session_id] = con.[session_id] 
  CROSS APPLY sys.Dm_exec_sql_text(req.sql_handle) AS st
  WHERE ses.[login_name] = N''

これらのセッションは関数のみを実行します。なぜこれが起こっているのかわかりません。これは正常な動作ですか?

enter image description here

2
user9516827

次のような関連テーブルをクエリしたい場合があります。

...何も起こらなくても、何が起こっているかの概要を知ること。

実行中のタスク(およびその他のもの)のクエリ

このようなものを実行して、システムで何が起こっているか、どのリソースが使用されているかを確認します。

SELECT des1.session_id AS Session_ID_S,
       --des1.context_info as Session_Contxt_Info,
       --dec1.session_id AS Session_ID_C,
       dowt.session_id AS Session_ID_WT,
       dowt.exec_context_id AS Exec_Contxt_ID,
       sdb.name AS DatabaseName,
       ssp.name AS SQL_Login_Name,
       des1.nt_user_name AS NT_User_Name,
       --'--kill ' + cast(dec1.session_id as nvarchar(20)) as killcommand,
       dowt.wait_duration_ms AS Wait_Duration_ms,
       dowt.wait_type AS Wait_Type,
       dowt.blocking_session_id AS Blocking_Session_ID,
       dowt.resource_description AS Ressource_Description,
       des1.program_name AS Program_Name,
       dest.[text] AS SQL_Text,
       deqp.query_plan AS Query_Plan,
       des1.cpu_time AS CPU_Time,
       des1.memory_usage AS RAM_Usage
FROM   sys.dm_exec_sessions AS des1
       LEFT 
       JOIN sys.dm_exec_connections AS dec1    
            ON  des1.session_id = dec1.session_id
       LEFT -- comment out LEFT to display only sessions that have gone parallel
       JOIN sys.dm_os_waiting_tasks AS dowt 
            ON  des1.session_id = dowt.session_id
       LEFT -- comment out LEFT to display only sessions currently executing statements
       JOIN sys.dm_exec_requests AS der    
            ON  des1.session_id = der.session_id
       LEFT 
       JOIN sys.server_principals AS ssp  
            ON  des1.login_name = ssp.name
       LEFT 
       JOIN sys.databases as sdb
            ON des1.database_id = sdb.database_id
       OUTER APPLY sys.dm_exec_sql_text(der.sql_handle) AS dest -- Retrieve Actual SQL Text
       OUTER APPLY sys.dm_exec_query_plan(der.plan_handle) AS deqp -- Retrieve Query Plan (XML)
WHERE  des1.is_user_process = 1
ORDER BY
       des1.session_id, dowt.exec_context_id     

クエリ出力

実行中のすべてのタスクの概要と、並列プロセス(CXCONSUMER/CXPACKET)がある場合に「root」セッションが作成されたアカウントを示します。出力の例は、次のスクリーンショットのようになります。

Picture of a process gone parallel

出力は、コメント化したLEFTコマンドの数によって異なります。それらをすべてそのままにしておくと、すべてのセッションの完全なリストが表示されます(システムセッションなしsession_id < 50)と問題を特定できるはずです。

質問に答える

ユーザーがアプリケーションにログインして別のモジュールに切り替えた後、同じモジュールに戻って重複セッションが作成され、実際のセッションが開いたままになっている場合に発生しますか?

それは答えられないことです。アプリケーションがどのように設計されているか、またモジュールスイッチが新しい接続を開始するかどうかはわかりません。

アプリケーションのバックグラウンドでなんらかの形のスレッドが発生している場合は、データベースの各接続のスレッドを監視しているだけかもしれません(例の出力[〜#〜]または[〜#〜]クエリオプティマイザがクエリを決定したため、クエリが並行して実行されていることがわかります並列処理が(部分的に)最適です。

次の例のように、ログイン名のないセッションが引き続き表示される場合:

Image of sessions without Login Name

...少なくとも、どのアプリケーション/プログラム/ステートメント/ 待機タイプ が問題の原因であるかを確認できます。この情報を利用して、さらに掘り下げることができます。

2