利用可能なスレッドがあるのに、なぜTHREADPOOLを待機させるのですか?

Aug 16 2020

アプリケーションのタイムアウトが発生しており、First Responder Kitを使用して、詳細をキャプチャしました。私の注意を引いたものの1つは次のとおりでした:

ポイズン待機が検出されました:スレッドプール

だから私は以下のクエリを実行しました:

---get thread pool waits---thread pool wait query
SELECT count(*) FROM sys.dm_os_waiting_tasks 
 where wait_type ='threadpool'

-- get threads available--Threads available query
 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',
    Getdate() as 'DateLogged'
from  
    sys.dm_os_Schedulers where status='VISIBLE ONLINE'

「スレッドプール待機」クエリを実行すると、スレッドプール待機が上記の結果(場合によっては20を超える結果)に数分の1秒間表示され、再度実行すると消えます。しかし、「threads available」クエリを介して、2番目の結果セットで400を超えるスレッドが使用可能であることがわかりました。

THREADPOOL最初のクエリを実行したときに待機が表示される理由を理解できませんが、2番目のクエリはスレッドがまだ使用可能であることを示しています。誰か説明してもらえますか?

  • Maxdop:8
  • 最大並列度:50

スレッドプールは待機します:

回答

4 JoshDarnell Aug 27 2020 at 21:38

最初のクエリを実行したときにTHREADPOOLが待機する理由を理解できませんが、2番目のクエリはスレッドがまだ使用可能であることを示しています。誰か説明してもらえますか?

THREADPOOLSQL Serverがオペレーティングシステムからスレッドを取得している間、非常に短い待機時間(それぞれ数ミリ秒)がたくさん見られることがわかりました。

これは、たとえば、SQL Serverがしばらくアイドル状態で、その後、複数の並列クエリが一度に実行された場合に発生する可能性があります。これらのクエリは、OSがsqlservr.exeプロセスにスレッドを提供している間待機する必要があり、THREADPOOLその間待機が蓄積されます。

「プロセス」->「スレッド数」PerfMonカウンターを見ると、これが発生していることを確認できます。一般に、この値が急速に上昇するときはいつでも、これらのTHREADPOOL待機が表示される場合があります。

私のブログ(Unusual THREADPOOL Waits)にこの動作の完全なデモがあります。要約は次のとおりです。

そのドキュメントリンクに戻る:

タスクがワーカーの実行を待機しているときに発生します。

通常の場合、これは、SQLServerが一度に持つことができるワーカースレッドの数に対して設定した論理制限に達したためです。

まれなケースでは、SQL Serverがワーカーをバックアップするために必要なスレッドを割り当てている(OSからのスレッドを要求している)ため、タスクはワーカーを待機しています。

明確にするために、これらの待機がアプリケーションのタイムアウトの原因であった場合、私は驚きます。