sql >> データベース >  >> RDS >> Database

ニージャーク待機統計:SOS_SCHEDULER_YIELD

    前回の投稿では、LCK_M_XX、ASYNC_NETWORK_IO、およびOLEDBの待機と、それらに対するひざまずく反応について説明しました。この投稿では、待機統計のテーマを続行し、SOS_SCHEDULER_YIELD待機について説明します。

    SOS_SCHEDULER_YIELDがサーバーで最も普及している場合、CPU使用率が持続的に高くなるのが一般的です。ここでのひざまずく反応は、サーバーがCPUの負荷にさらされている必要があるか、スピンロックが問題であるということです。

    これら2つの反応を理解するには、ここで少し背景が必要です。

    スレッドのスケジューリング

    SQL Serverのスレッドスケジューリングは、WindowsではなくSQL Server自体によって管理されます(つまり、プリエンプティブではありません)。 StorageEngineのSQLOS部分は、スケジューリング機能を提供し、スレッドは、プロセッサでの実行(スレッドの状態がRUNNING)から、リソースが使用可能になるのを待機しているウェイターリスト(状態はSUSPENDED)から、実行可能であるまでに移行します。リソースが使用可能になり(状態はRUNNABLE)、キューの先頭に到達して再びプロセッサに戻る(RUNNINGの状態に戻る)のを待ってキューに入れます。プロセッサー、ウェイターリスト、および実行可能キューを大文字にして、スケジューラーの一部として識別しました。

    スレッドがすぐに取得できないリソースを必要とするときはいつでも、スレッドは一時停止され、ウェイターリストでそのリソースが利用可能であることが通知(通知)されるのを待ちます。ウェイターリストに費やされた時間はリソース待機時間であり、ランナブルキューに費やされた時間はシグナル待機時間です。一緒にそれらが組み合わさって、全体的な待機時間になります。 SQL OSは待機時間と信号待機時間を追跡するため、sys.dm_os_wait_statsからの出力に対していくつかの計算を行って、リソース待機時間を導出する必要があります(ここにある私のスクリプトを参照してください)。

    ウェイターリストは順序付けられておらず(その上の任意のスレッドはいつでも通知され、実行可能キューに移動できます)、実行可能キューはほぼ100%の時間で先入れ先出し(FIFO)です。ランナブルキューがFIFOである唯一の例外は、複数のリソースガバナーワークロードグループが同じリソースプールに構成されており、それらが相互に異なる優先順位を持っている場合です。これが本番環境で正常に使用されるのを見たことがないので、これ以上説明しません。

    スレッドがプロセッサから移動する必要があるもう1つの理由があります。それは、そのクォンタムを使い果たします。 SQLOSのスレッドクォンタムは4ミリ秒に固定されています。スレッド自体は、そのクォンタムが使い果たされたことを判断し(SQL OSのヘルパールーチンを呼び出すことによって)、プロセッサを自発的に放棄する(yieldingとして知られています)責任があります。これが発生すると、スレッドは待機するものがないため、実行可能キューの一番下に直接移動します。ただし、SQL OSは、プロセッサからのこの移行の待機タイプを登録し、SOS_SCHEDULER_YIELDを登録する必要があります。

    この動作はCPUの負荷と間違われることがよくありますが、そうではありません。CPUの使用量が持続しているだけです。 CPUのプレッシャーとそれを認識することは、将来の投稿のためのまったく別のトピックです。この投稿に関する限り、平均信号待機時間が短い(0-0.1-0.2ms)限り、CPUの負荷が問題にならないことは間違いありません。

    スピンロック

    スピンロックは非常に低レベルの同期プリミティブであり、SQL Serverの非常に高温のデータ構造(非常に揮発性が高く、複数のスレッドによって非常に頻繁にアクセスおよび変更される)へのスレッドセーフなアクセスを提供するために使用されます。このような構造の例としては、バッファプールの各部分のバッファ空きリストや、ファイルグループ内のデータファイルの比例塗りつぶし配列があります。

    スレッドがスピンロックを取得する必要がある場合、スピンロックが空いているかどうかを確認し、空いている場合はすぐに取得します(「テストビットのクリアと設定」などのインターロックされたアセンブリ言語プリミティブを使用)。スピンロックを取得できない場合、スレッドはすぐにそれを取得しようとします。また、最大1000回の反復で、元に戻るまで(少しスリープします)、何度も何度も取得を試みます。スレッドはWindowsのsleep()関数を呼び出すだけなので、これは待機タイプとして登録されませんが、待機している他のスレッドは、スリープしているスレッドがそれまでプロセッサ上にとどまるため、大きな(10〜20ms +)信号待機時間を作ることができます。スピンロックを取得します。

    なぜ私はスピンロックについて話しているのですか?また、CPU使用率が高くなる原因となる可能性があり、スピンロックがSOS_SCHEDULER_YIELD待機の原因であるという誤解があるためです。そうではありません。

    SOS_SCHEDULER_YIELDの原因

    したがって、SOS_SCHEDULER_YIELDには1つの原因があります。スレッドがそのスケジューリングクォンタムを使い果たし、インスタンスが頻繁に繰り返されると、SOS_SCHEDULER_YIELDが最も一般的な待機であり、CPU使用率が高くなる可能性があります。

    スレッドが待機していないため、sys.dm_os_waiting_tasksからの出力にSOS_SCHEDULER_YIELD待機が表示されません。 sys.dm_exec_requestsをクエリし、last_wait_type列でフィルタリングすることにより、SOS_SCHEDULER_YIELD待機を生成しているクエリを確認できます。

    これは、sys.dm_os_wait_statsの出力にSOS_SCHEDULER_YIELDが表示されている場合、実際には待機していなかったため、リソース待機はゼロになることも意味します。ただし、これらの「待機」のそれぞれは、クエリで発生した4ミリ秒のCPU時間に等しいことに注意してください。

    SOS_SCHEDULER_YIELD待機の原因を証明する唯一の方法は、拡張イベントとMicrosoftのデバッグシンボルを使用して、待機タイプが発生したときにSQLServer呼び出しスタックをキャプチャすることです。その調査の実行方法を説明および示すブログ投稿があります。スピンロックとスピンロック調査に関する優れたホワイトペーパーがあり、その内部の深さに興味がある場合は読む価値があります。

    量子枯渇の場合、それが根本的な原因ではありません。それはさらなる症状です。ここで、スレッドがそのクォンタムを繰り返し使い果たしている理由を検討する必要があります。

    スレッドは、別のスレッドが所有するリソースを必要とせずに4ミリ秒間SQL Serverコードの処理を続行できる場合にのみ、その量を使い果たすことができます。ロック、ページラッチ、ディスクから読み取られるデータファイルページ、メモリ割り当て、ファイルの拡張、ロギングを待つ必要はありません。 、またはスレッドが必要とする可能性のある他の無数のリソース。

    クォンタムの枯渇が発生し、大量のSOS_SCHEDULER_YIELD待機が発生する可能性がある最も一般的なコードは、必要なすべてのデータファイルページがメモリ内にあり、それらのページへのアクセスの競合がないインデックス/テーブルをスキャンすることです。 SOS_SCHEDULER_YIELDが最上位の待機タイプ(大規模および/または繰り返しのインデックス/テーブルスキャン)である場合は、クエリプランを探すことをお勧めします。

    これは、大規模なスキャンが悪いと言っているわけではありません。ワークロードを処理する最も効率的な方法はスキャンによるものである可能性があるためです。ただし、SOS_SCHEDULER_YIELD待機が新しくて異常であり、大規模なスキャンが原因である場合は、クエリプランがスキャンを使用している理由を調査する必要があります。誰かが重要な非クラスター化インデックスを削除したか、統計が古くなっているために誤ったクエリプランが選択されたか、異常なパラメータ値がストアドプロシージャに渡され、クエリプランがスキャンまたはコード変更を要求した可能性がありますインデックスの追加をサポートせずに発生しました。

    概要

    他の待機タイプと同様に、SOS_SCHEDULER_YIELDの意味を正確に理解することは、SOS_SCHEDULER_YIELDのトラブルシューティング方法と、処理中のワークロードが原因で動作が予想されるかどうかを理解するための鍵です。

    一般的な待機統計に関する限り、パフォーマンスのトラブルシューティングにそれらを使用する方法の詳細については、次のURLを参照してください。

    • 待機統計から始まる私のSQLskillsブログ投稿シリーズ、またはどこが痛いのか教えてください
    • 待機タイプとラッチクラスのライブラリはこちら
    • 私のPluralsightオンライントレーニングコースSQLServer:待機統計を使用したパフォーマンスのトラブルシューティング
    • SQL Sentry Performance Advisor

    シリーズの次の記事では、ひざのけいれん反応の一般的な原因である別の待機タイプについて説明します。それまでは、トラブルシューティングを行ってください。


    1. FORのSQLクエリ動的テーブル名

    2. SQLDeveloperアイコン

    3. 他の2つのVarchar列の連結を表す列を追加します

    4. SQL Serverの「rowversion」とは何ですか?