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

オブザーバーのオーバーヘッドと待機タイプの症状

    多くの人が、私と同じように、全体的なパフォーマンスのトラブルシューティング方法の一部として待機統計を使用します。そのため、この投稿で調査したい質問は、オブザーバーのオーバーヘッドに関連する待機タイプに関するものです。オブザーバーのオーバーヘッドとは、SQLプロファイラー、サーバー側のトレース、または拡張イベントセッションによって引き起こされるSQLServerのワークロードスループットへの影響を意味します。 オブザーバーのオーバーヘッドに関する詳細については、同僚のJonathanKehayiasからの次の2つの投稿を参照してください

    • SQLトレースと拡張イベントの「オブザーバーオーバーヘッド」の測定
    • SQLServer2012でのquery_post_execution_showplan拡張イベントの影響

    したがって、この投稿では、オブザーバーのオーバーヘッドのいくつかのバリエーションを見ていき、測定された劣化に関連する一貫した待機タイプを見つけることができるかどうかを確認したいと思います。 SQL Serverユーザーが実稼働環境でトレースを実装する方法はさまざまであるため、結果は異なる場合がありますが、いくつかの幅広いカテゴリをカバーし、見つけたものについて報告したいと思います。

    • SQLプロファイラーセッションの使用法
    • サーバー側のトレースの使用法
    • サーバー側のトレースの使用、低速のI/Oパスへの書き込み
    • リングバッファターゲットを使用した拡張イベントの使用
    • ファイルターゲットでの拡張イベントの使用
    • 低速のI/Oパス上のファイルターゲットでの拡張イベントの使用
    • イベント損失のない低速I/Oパス上のファイルターゲットでの拡張イベントの使用

    テーマの他のバリエーションを考えることができる可能性があります。この投稿のコメントとして、オブザーバーのオーバーヘッドに関する興味深い調査結果を共有し、統計を待つことをお勧めします。

    ベースライン

    テストには、4つのvCPUと4GBのRAMを搭載したVMware仮想マシンを使用しました。私の仮想マシンのゲストはOCZVertexSSDを使用していました。オペレーティングシステムはWindowsServer2008 R2 Enterpriseで、SQL Serverのバージョンは2012、SP1CU4です。

    「ワークロード」については、2008 Creditサンプルデータベースに対してループで読み取り専用クエリを使用しており、GOを10,000,000回に設定しています。

    USE [Credit];
    GO
     
    SELECT TOP 1 
         [member].[member_no],
         [member].[lastname],
         [payment].[payment_no],
         [payment].[payment_dt],
         [payment].[payment_amt]
    FROM [dbo].[payment]
    INNER JOIN [dbo].[member]
    ON [member].[member_no] = [payment].[member_no];
    GO 10000000

    また、16の同時セッションを介してこのクエリを実行しています。私のテストシステムの最終結果は、仮想ゲストのすべてのvCPUで100%のCPU使用率であり、2分間で1秒あたり平均14,492のバッチリクエストです。

    イベントトレースに関しては、各テストでShowplan XML Statistics Profileを使用しました SQLプロファイラーとサーバー側のトレーステストの場合–およびquery_post_execution_showplan 拡張イベントセッションの場合。実行計画イベントは非常にです 高価なため、極端な状況下で待機タイプのテーマを導き出すことができるかどうかを確認できるように、それらを選択しました。

    テスト期間中の待機タイプの累積をテストするために、次のクエリを使用しました。特別なことは何もありません–統計をクリアし、2分間待ってから、劣化テスト期間中のSQL Serverインスタンスの上位10の待機累積を収集します:

    -- Clearing the wait stats
     
    DBCC SQLPERF('waitstats', clear);
     
    WAITFOR DELAY '00:02:00';
    GO
     
    SELECT TOP 10
         [wait_type],
         [waiting_tasks_count],
         [wait_time_ms]
    FROM sys.[dm_os_wait_stats] AS [ws]
    ORDER BY [wait_time_ms] DESC;

    私はそうではないことに注意してください 通常は除外されるバックグラウンド待機タイプを除外します。これは、通常は害のないものを排除したくなかったためですが、この状況では、実際にはさらに調査するための実際の領域を指しています。

    SQLプロファイラーセッション

    次の表は、ローカルSQLプロファイラートレーストラッキングShowplan XML Statistics Profileを有効にした場合の1秒あたりの前後のバッチリクエストを示しています。 (SQL Serverインスタンスと同じVMで実行):

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーセッションバッチリクエスト
    (平均2分)
    14,492 1,416

    SQLプロファイラートレースによってスループットが大幅に低下することがわかります。

    同じ期間の累積待機時間については、上位の待機タイプは次のとおりです(この記事の残りのテストと同様に、いくつかのテストを実行しましたが、出力は概ね一貫していました):

    wait_type waiting_tasks_count wait_time_ms
    TRACEWRITE 67,142 1,149,824
    FT_IFTS_SCHEDULER_IDLE_WAIT 4 237,003
    SLEEP_TASK 313 180,449
    REQUEST_FOR_DEADLOCK_SEARCH 24 120,111
    HADR_FILESTREAM_IOMGR_IOCOMPLETION 240 120,086
    LAZYWRITER_SLEEP 120 120,059
    DIRTY_PAGE_POLL 1,198 120,038
    HADR_WORK_QUEUE 12 120,015
    LOGMGR_QUEUE 937 120,011
    SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120,006

    私に飛び出す待機タイプはTRACEWRITEです –これは、Books Onlineによって、「SQLトレース行セットトレースプロバイダーが空きバッファーまたはイベントを含むバッファーのいずれかを処理するのを待機するときに発生する」待機タイプとして定義されています。残りの待機タイプは、通常、結果セットから除外される標準のバックグラウンド待機タイプのように見えます。さらに、2011年にオブザーバーのオーバーヘッドと呼ばれる記事で、オーバートレースに関する同様の問題について話しました。これは、トレースが多すぎるという危険性です。そのため、この待機タイプに精通していました時々 オブザーバーのオーバーヘッドの問題を適切に指し示します。さて、私がブログに書いたその特定のケースでは、それはSQLプロファイラーではなく、行セットトレースプロバイダーを使用する別のアプリケーションでした(非効率的)。

    サーバー側のトレース

    これはSQLプロファイラーの場合でしたが、サーバー側のトレースオーバーヘッドについてはどうでしょうか。次の表は、ローカルサーバー側のトレースによるファイルへの書き込みを有効にした場合の1秒あたりの前後のバッチリクエストを示しています。

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーバッチリクエスト
    (平均2分)
    14,492 4,015

    上位の待機タイプは次のとおりです(いくつかのテストを実行しましたが、出力は一貫していました):

    wait_type waiting_tasks_count wait_time_ms
    FT_IFTS_SCHEDULER_IDLE_WAIT 4 237,015
    SLEEP_TASK 253 180,871
    SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120,046
    HADR_WORK_QUEUE 12 120,042
    REQUEST_FOR_DEADLOCK_SEARCH 24 120,021
    XE_DISPATCHER_WAIT 3 120,006
    WAITFOR 1 120,000
    LOGMGR_QUEUE 931 119,993
    DIRTY_PAGE_POLL 1,193 119,958
    XE_TIMER_EVENT 55 119,954

    今回はTRACEWRITEは表示されません (現在、ファイルプロバイダーを使用しています)およびその他のトレース関連の待機タイプである、文書化されていないSQLTRACE_INCREMENTAL_FLUSH_SLEEP 上昇しましたが、最初のテストと比較すると、累積待機時間は非常に似ています(120,046対120,006)。同僚のErin Stellato(@erinstellato)は、彼女の投稿でこの特定の待機タイプについて話しました。 。したがって、他の待機タイプを見ると、信頼できる危険信号として飛び出しているものはありません。

    低速のI/Oパスへのサーバー側トレースの書き込み

    サーバー側のトレースファイルを低速ディスクに配置するとどうなりますか?次の表は、USBスティック上のファイルに書き込むローカルサーバー側のトレースを有効にした場合の1秒あたりの前後のバッチリクエストを示しています。

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーバッチリクエスト
    (平均2分)
    14,492 260

    ご覧のとおり、前のテストと比較しても、パフォーマンスは大幅に低下しています。

    上位の待機タイプは次のとおりです。

    wait_type waiting_tasks_count wait_time_ms
    SQLTRACE_FILE_BUFFER 357 351,174
    SP_SERVER_DIAGNOSTICS_SLEEP 2,273 299,995
    SLEEP_TASK 240 194,264
    FT_IFTS_SCHEDULER_IDLE_WAIT 2 181,458
    REQUEST_FOR_DEADLOCK_SEARCH 25 125,007
    LAZYWRITER_SLEEP 63 124,437
    LOGMGR_QUEUE 941 120,559
    HADR_FILESTREAM_IOMGR_IOCOMPLETION 67 120,516
    WAITFOR 1 120,515
    DIRTY_PAGE_POLL 1,204 120,513

    このテストに飛び出す待機タイプの1つは、文書化されていないSQLTRACE_FILE_BUFFERです。 。これについてはあまり文書化されていませんが、名前に基づいて、知識に基づいて推測することができます(特にこの特定のテストの構成を考えると)。

    リングバッファターゲットへの拡張イベント

    次に、拡張イベントセッションに相当するものの調査結果を確認しましょう。次のセッション定義を使用しました:

    CREATE EVENT SESSION [ApplicationXYZ] ON SERVER
      ADD EVENT sqlserver.query_post_execution_showplan,
      ADD TARGET package0.ring_buffer(SET max_events_limit=(1000))
      WITH (STARTUP_STATE=ON);
    GO

    次の表は、リングバッファターゲット(query_post_execution_showplanをキャプチャする)でXEセッションを有効にした場合の1秒あたりの前後のバッチリクエストを示しています。 イベント):

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーバッチリクエスト
    (平均2分)
    14,492 4,737

    上位の待機タイプは次のとおりです。

    wait_type waiting_tasks_count wait_time_ms
    SP_SERVER_DIAGNOSTICS_SLEEP 612 299,992
    FT_IFTS_SCHEDULER_IDLE_WAIT 4 237,006
    SLEEP_TASK 240 181,739
    LAZYWRITER_SLEEP 120 120,219
    HADR_WORK_QUEUE 12 120,038
    DIRTY_PAGE_POLL 1,198 120,035
    REQUEST_FOR_DEADLOCK_SEARCH 24 120,017
    SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120,011
    LOGMGR_QUEUE 936 120,008
    WAITFOR 1 120,001

    XE関連として飛び出したものはなく、バックグラウンドタスクの「ノイズ」のみです。

    ファイルターゲットへの拡張イベント

    リングバッファターゲットの代わりにファイルターゲットを使用するようにセッションを変更するのはどうですか?次の表は、リングバッファターゲットではなくファイルターゲットを使用してXEセッションを有効にした場合の1秒あたりの前後のバッチリクエストを示しています。

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーバッチリクエスト
    (平均2分)
    14,492 4,299

    上位の待機タイプは次のとおりです。

    wait_type waiting_tasks_count wait_time_ms
    SP_SERVER_DIAGNOSTICS_SLEEP 2,103 299,996
    FT_IFTS_SCHEDULER_IDLE_WAIT 4 237,003
    SLEEP_TASK 253 180,663
    LAZYWRITER_SLEEP 120 120,187
    HADR_WORK_QUEUE 12 120,029
    SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120,019
    REQUEST_FOR_DEADLOCK_SEARCH 24 120,011
    WAITFOR 1 120,001
    XE_TIMER_EVENT 59 119,966
    LOGMGR_QUEUE 935 119,957

    XE_TIMER_EVENTを除いて、何もありません 、XE関連として飛び出しました。 Bob Wardの待機タイプリポジトリは、何か問題がない限り、これを無視しても安全だと言っていますが、パフォーマンスの低下中にシステムの9箇所にあった場合、現実的にはこの通常は無害な待機タイプに気付くでしょうか。また、通常は良性であるために、すでに除外している場合はどうなりますか?

    低速のI/Oパスファイルターゲットへの拡張イベント

    では、ファイルを低速のI / Oパスに配置するとどうなりますか?次の表は、USBスティック上のファイルターゲットとのXEセッションを有効にした場合の1秒あたりの前後のバッチリクエストを示しています。

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーバッチリクエスト
    (平均2分)
    14,492 4,386

    上位の待機タイプは次のとおりです。

    wait_type waiting_tasks_count wait_time_ms
    FT_IFTS_SCHEDULER_IDLE_WAIT 4 237,046
    SLEEP_TASK 253 180,719
    HADR_FILESTREAM_IOMGR_IOCOMPLETION 240 120,427
    LAZYWRITER_SLEEP 120 120,190
    HADR_WORK_QUEUE 12 120,025
    SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120,013
    REQUEST_FOR_DEADLOCK_SEARCH 24 120,011
    WAITFOR 1 120,002
    DIRTY_PAGE_POLL 1,197 119,977
    XE_TIMER_EVENT 59 119,949

    繰り返しますが、XE_TIMER_EVENTを除いて、XE関連のジャンプアウトはありません。 。

    遅いI/Oパスファイルターゲットへの拡張イベント、イベント損失なし

    次の表は、USBスティック上のファイルターゲットとのXEセッションを有効にした場合の、1秒あたりの前後のバッチ要求を示していますが、今回はイベント損失(EVENT_RETENTION_MODE =NO_EVENT_LOSS)を許可していません。これは推奨されておらず、表示されます。結果では、その理由は次のとおりです。

    1秒あたりのベースラインバッチリクエスト
    (平均2分)
    1秒あたりのSQLプロファイラーバッチリクエスト
    (平均2分)
    14,492 539

    上位の待機タイプは次のとおりです。

    wait_type waiting_tasks_count wait_time_ms
    XE_BUFFERMGR_FREEBUF_EVENT 8,773 1,707,845
    FT_IFTS_SCHEDULER_IDLE_WAIT 4 237,003
    SLEEP_TASK 337 180,446
    LAZYWRITER_SLEEP 120 120,032
    DIRTY_PAGE_POLL 1,198 120,026
    HADR_WORK_QUEUE 12 120,009
    REQUEST_FOR_DEADLOCK_SEARCH 24 120,007
    SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120,006
    WAITFOR 1 120,000
    XE_TIMER_EVENT 59 119,944

    スループットが大幅に低下すると、XE_BUFFERMGR_FREEBUF_EVENTが表示されます。 累積待機時間の結果で1位にジャンプします。これはです Books Onlineに記載されており、Microsoftによると、このイベントは、イベントが失われないように構成されたXEセッションに関連付けられており、セッション内のすべてのバッファーがいっぱいになっています。

    オブザーバーの影響

    待機タイプは別として、各監視方法がバッチ要求を処理するワークロードの機能にどのような影響を与えたかに注目するのは興味深いことでした。


    1秒あたりのバッチリクエストに対するさまざまな監視方法の影響>

    すべてのアプローチで、ベースライン(観察なし)と比較して、重大な(ただし衝撃的ではない)ヒットがありました。ただし、プロファイラーを使用する場合、サーバー側のトレースを低速のI / Oパスに使用する場合、または拡張イベントを低速のI / Oパス上のファイルターゲットに使用する場合に最も苦痛を感じましたが、イベントが失われないように構成されている場合に限ります。イベントが失われると、このセットアップは実際には、高速I / Oパスへのファイルターゲットと同等に実行されました。これは、おそらく、より多くのイベントをドロップできたためです。

    概要

    考えられるすべてのシナリオをテストしたわけではなく、他にも興味深い組み合わせがあります(SQL Serverのバージョンに基づくさまざまな動作は言うまでもありません)が、この調査から得た重要な結論は、明らかな待機タイプの蓄積に常に依存できるとは限らないということです。オブザーバーのオーバーヘッドシナリオに直面したときのポインター。この投稿のテストに基づくと、7つのシナリオのうち3つだけが、正しい方向を示すのに役立つ可能性のある特定の待機タイプを示しました。それでも、これらのテストは制御されたシステムで行われ、多くの場合、前述の待機タイプは無害なバックグラウンドタイプとして除外されるため、まったく表示されない可能性があります。

    これを考えると、あなたは何ができますか?明確または明らかな症状のないパフォーマンスの低下については、トレースとXEセッションについて質問する範囲を広げることをお勧めします(余談ですが、システムが仮想化されているか、電源オプションが正しくない可能性がある場合は、範囲を広げることもお勧めします)。たとえば、システムのトラブルシューティングの一環として、sys.[traces]を確認します。 およびsys.[dm_xe_sessions] 予期しない何かがシステムで実行されているかどうかを確認します。これは、心配する必要のある追加のレイヤーですが、いくつかの簡単な検証を行うことで、時間を大幅に節約できます。


    1. 値を1つのフィールドから2つに分割

    2. MacにSQLServer2019をインストールする

    3. Oracleでチェック制約を使用する方法

    4. SQLステートメントのバックティックと角括弧の違いは何ですか?