web-dev-qa-db-ja.com

どのSPIDがどのスケジューラ(ワーカースレッド)を使用しているかを確認することはできますか?

最近、SQL Server 2014 HADR環境で問題が発生しました。このサーバーでは、サーバーの1つがワーカースレッドを使い果たしました。メッセージを受け取りました:

AlwaysOn可用性グループのスレッドプールは、使用可能なワーカースレッドが十分にないため、新しいワーカースレッドを開始できませんでした

可用性グループの1つを別のサーバーに移動することで問題を "解決"できましたが、どのクエリがどのスケジューラー(またはワーカー、タスク)で実行されているかを確認できるかどうか疑問に思っていました。

次のクエリを使用すると、使用可能でリソースを待機している利用可能なワーカーの数を確認できます。

declare @max int
select @max = max_workers_count from sys.dm_os_sys_info

select 
    @max as 'TotalThreads',
    sum(active_Workers_count) as 'CurrentThreads',
    @max - sum(active_Workers_count) as 'AvailableThreads',
    sum(runnable_tasks_count) as 'WorkersWaitingForCpu',
    sum(work_queue_count) as 'RequestWaitingForThreads' ,
    sum(current_workers_count) as 'AssociatedWorkers'
from  
    sys.dm_os_Schedulers where status='VISIBLE ONLINE'

次のクエリを使用すると、どのワーカーがどのCPU(コア)で実行されているかを確認できます。

SELECT *
FROM  sys.dm_os_Schedulers s --> Prozessoren Kerne
JOIN sys.dm_os_workers w ON w.scheduler_address = s.scheduler_address
JOIN sys.dm_os_tasks t ON t.task_address = w.task_address
WHERE s.status = 'VISIBLE ONLINE'
AND s.cpu_id = 2

どのSPID(および最終的にはどのクエリ)がどのスレッドで実行されているかを見つける方法はありますか?

私はすでにしばらく探していましたが、スケジューラ、ワーカー、スレッド間の接続に関するいくつかの興味深い情報を見つけましたが、それが可能であるかどうかを示すものは何もありませんでした。

どのデータベースが非常に多くのワーカースレッドを使用しているかを確認したいと思います。 (私の意見では)実動サーバーに属していないデータベースがいくつかあります。チェックするときsys.dm_exec_requestsあまり進んでいないようです。

環境は1年以上同じ構成で問題なく実行されています。問題のサーバーには24個のCPUと5個のAGがあり、合計325のデータベースがあります。 3つのAGがプライマリです。この問題を回避するために、サーバーからセカンダリへの50個のデータベースでAGに失敗しました。

6
Dan Stef

ソロモン・ラッキーのおかげで

scheduler_idsys.dm_exec_requests列に関連付けてみましたか?

探していた情報を得ることができました。

このクエリで、どのセッションがどのCPU_ID(スケジューラー)を使用しているかを確認できます。

SELECT
    s.cpu_id,
    s.status,
    db_name(r.database_id) as [databaseName],
    w.last_wait_type, 
    w.return_code,
    t.task_state,
    t.pending_io_count,
    t.session_id,
    r.sql_handle
FROM  sys.dm_os_Schedulers s 
JOIN sys.dm_os_workers w 
    ON w.scheduler_address = s.scheduler_address
JOIN sys.dm_os_tasks t 
    ON t.task_address = w.task_address
JOIN sys.dm_exec_requests r 
    ON r.scheduler_id = s.scheduler_id
order by 1,3

実行中のSQLステートメントを取得するには、クエリを次のように変更します。

SELECT
    s.cpu_id,
    s.status,
    db_name(r.database_id) as [databaseName],
    w.last_wait_type, 
    w.return_code,
    t.task_state,
    t.pending_io_count,
    t.session_id,
    r.sql_handle,
    te.text
FROM  sys.dm_os_Schedulers s 
JOIN sys.dm_os_workers w 
    ON w.scheduler_address = s.scheduler_address
JOIN sys.dm_os_tasks t 
    ON t.task_address = w.task_address
JOIN sys.dm_exec_requests r 
    ON r.scheduler_id = s.scheduler_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) te   
order by 1,3

しかし、それは私に(明らかに)SQL_handleを持つタスクを与えるだけです。

そのサーバー上のほとんどのスレッドは、システム自体がすべての同期を保つために使用しているようです。労働者のほとんどは「システムジョブ」として使用されています。これらのタスクのlast_wait_typeは、主にREDO_THREAD_PENDING_WORKまたはHADR_WORK_QUEUEです。

探していた答えはありますが、問題の原因はまだわかりませんでした。別の質問を開きます( ワーカースレッドを使用しているのは誰ですか?SQL Server 2014-HADR )。

4
Dan Stef