多くの人が、私と同じように、全体的なパフォーマンスのトラブルシューティング方法の一部として待機統計を使用します。そのため、この投稿で調査したい質問は、オブザーバーのオーバーヘッドに関連する待機タイプに関するものです。オブザーバーのオーバーヘッドとは、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]
予期しない何かがシステムで実行されているかどうかを確認します。これは、心配する必要のある追加のレイヤーですが、いくつかの簡単な検証を行うことで、時間を大幅に節約できます。