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

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

    過去18か月間、私は統計分析やその他のパフォーマンス調整関連のトピックを待つためのひざまずく反応に焦点を当ててきました。この投稿では、それを続けて PAGELATCH_XXについて説明します。 待ちます。待機の最後のXXは、複数のタイプの PAGELATCHがあることを意味します。 待ってください。最も一般的な例は次のとおりです。

    • PAGELATCH_SH –( SH )ページの内容を読み取ることができるように、メモリ内のデータファイルページへのアクセスを待機しています
    • PAGELATCH_EX またはPAGELATCH_UP –( EX 包括的またはUP 日付)ページの内容を変更できるように、メモリ内のデータファイルページへのアクセスを待機しています

    これらの待機タイプの1つがサーバーで最も一般的である場合、ひざまずく反応は、問題がI / Oに関係していることです(つまり、 PAGEIOLATCH_XX との混同) 待機タイプ(2014年の投稿で取り上げました)で、誰かがメモリを追加したり、I/Oサブシステムを微調整したりしようとしました。競合中のデータファイルページはすでにバッファプールのメモリにあるため、これらの反応はまったく効果がありません!

    いずれの場合も、 PAGELATCH_XXに問題があるかどうかを確認できます。 sys.dm_os_waiting_tasksを使用した競合 この投稿で(別の待機タイプに対して)示されているように、ブログのスクリプトまたはPerformanceAdvisorなどのツールを使用します。

    では、競合の原因は何ですか?まず、これらの待機タイプの背景について説明し、次に PAGELATCH_XXの最も一般的な2つの原因について説明します。 競合。

    背景:ラッチ

    PAGELATCH_XXの原因のいくつかに入る前に 待っています、なぜそれらが存在するのかを説明したいと思います。

    マルチスレッドシステムでは、次のようなシナリオを防ぐために、複数のスレッドからアクセスして操作できるデータ構造を保護する必要があります。

    • 2つのスレッドがデータ構造を同時に更新し、更新の一部が失われます
    • データ構造を読み取る別のスレッドと同時にデータ構造を更新するスレッド。これにより、読み取りスレッドは古いデータと新しいデータの混合を認識します。

    これは基本的なコンピュータサイエンスであり、SQL Serverも例外ではないため、SQLServer内のすべてのデータ構造にマルチスレッドアクセス制御が必要です。

    SQL Serverがこれを行うために使用するメカニズムの1つはラッチと呼ばれ、ラッチを排他モードで保持すると他のスレッドがデータ構造にアクセスできなくなり、ラッチを共有モードで保持すると他のスレッドがデータ構造を変更できなくなります。 SQL Serverは、一部のデータ構造にもスピンロックを使用しています。これらについては、2014年のこの投稿で説明しました。

    しかし、なぜメモリ内のデータファイルページがラッチで保護されているのでしょうか。データファイルページは、特別な目的ではありますが、単なるデータ構造であるため、他のデータ構造と同じアクセス制御が必要です。したがって、1つのスレッドがデータファイルページを変更する必要がある場合は、ページの排他的または更新ラッチを取得する必要があります。待機できない場合は、待機タイプ PAGELATCH_EX またはPAGELATCH_UP 結果。

    古典的なtempdbの競合

    PAGELATCH tempdbでの競合は通常、割り当てビットマップで発生し、多数の同時接続で小さな一時テーブル(tempdbに格納されている)を作成および削除するワークロードで発生します。

    最初の行を一時テーブルに挿入するときは、2つのページを割り当てる必要があります(データページと、データページを追跡するIAMページ)。これらのページは、PFSページと呼ばれる特別な割り当てページで割り当て済みとしてマークする必要があり、デフォルトでは、SGAMページと呼ばれる別の割り当てページによって追跡される特別なデータエクステントから割り当てられます(これらの詳細は、私の古いブログ投稿にありますここ)。一時テーブルが削除された場合、これらのページの割り当てを再度解除する必要があり、PFSページとSGAMページにさらに変更を加える必要があります。

    一時テーブルが小さく、同時に作成されるすべての一時テーブルの累積サイズが64MB未満の場合、これらの割り当てビットマップの変更はすべて、tempdbデータファイルの最初のPFSページとSGAMページに集中します(ページID(1:1))。 1)と(1:3))。これらの割り当てページの1つを更新するには、ページをラッチする必要があり、一度に1つのスレッドのみがページを変更できるため、他のすべてのスレッドは待機する必要があります–待機タイプ PAGELATCH_UP

    SQL Server 2005以降、一時テーブルは、サイズが8MB未満である限り、削除時にキャッシュできます(SQL Server 2014では、一時テーブルにDDLステートメントもあるストアドプロシージャで作成されません)。これは、同じクエリプランを実行する次のスレッドが一時テーブルをキャッシュから取り出すことができ、初期割り当てを処理する必要がないことを意味します。これにより、割り当てビットマップの競合が削減されますが、一時テーブルキャッシュはそれほど大きくないため、数百の一時テーブルの作成/削除が同時に行われるワークロードでも、多くの競合が発生します。

    サーバーで文書化されたトレースフラグ1118を有効にすることで、tempdbのSGAMページでの競合を防ぐのは簡単です。これは、世界中のすべてのサーバーで有効にする必要があり、実際にはSQLServer2016では変更できないデフォルトの動作です。

    >

    tempdbのPFSページでの競合を防ぐことは少し難しいです。パフォーマンスのために一時テーブルが必要であると仮定すると、tempdbに複数のデータファイルを用意して、ファイル間で割り当てがラウンドロビンで行われ、競合が複数のPFSページに分割されるため、全体的な競合が減少します。残念ながら、必要なデータファイルの数について正しい答えはありません。これに関する一般的に受け入れられているガイダンスの詳細については、KB記事2154845およびこのブログ投稿を参照してください。

    ホットスポットを挿入

    ユーザーデータベースで、 PAGELATCH_EXの数が多い一般的な原因 待機は挿入ホットスポットです。

    これは、テーブルにintまたはbigintクラスターキーを持つクラスター化インデックスがあり、行サイズが十分に小さいため、クラスター化インデックスのリーフレベルで数十以上のテーブル行がデータページに収まる場合に発生する可能性があります。

    このようなテーブルの場合、ワークロードに数十または数百の同時スレッドがテーブルに挿入される場合、スレッドの多くは、同じリーフレベルのデータページに挿入する必要があるID値(したがってクラスターキー)を持つ行を生成します。

    ここで、メモリ内のデータファイルページに変更を加えるには専用のラッチが必要であるため、同じページに挿入しようとする各スレッドは、ページのラッチを排他的に取得する必要があることに注意してください。各スレッドが専用ラッチを保持している間、他のスレッドは PAGELATCH_EXを待機します。 そのページでは、基本的に、非常にボトルネックのある同期プロセスへの同時挿入を行います。

    この問題にはいくつかの修正があります:

    • よりランダムなキーを使用し、これによりインデックスの断片化が発生することを認識しているため、ページ分割を防ぐためにインデックスの塗りつぶし係数も使用してください
    • ある種の人工的な分割メカニズムを使用して、インサートをテーブルに広げます
    • より長いテーブル行サイズを使用します(これは明らかに最も口当たりの悪いオプションです)

    誰かがランダムなGUIDクラスターキーをintまたはbigintIDクラスターキーに変更してインデックスの断片化の問題を削除しようとしたときに、このような挿入ホットスポットが発生するのを見ましたが、本番環境での新しいテーブルスキーマのテストに失敗しました。

    >

    概要

    他の待機タイプと同様に、 PAGELATCH_XXが何であるかを正確に理解します。 待機平均は、それらのトラブルシューティング方法を理解するための鍵です。

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

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

    次回まで、トラブルシューティングをお楽しみください!


    1. MariaDBでのMONTH()のしくみ

    2. psql出力で通知を無効にする

    3. mysqlで次の自動インクリメントIDを取得する方法

    4. テーブルのすべての値をSQLの別のテーブルに挿入します