最近、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に失敗しました。
scheduler_id
のsys.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 )。