同僚のErinStellatoが最近、ExtendedEventsでイベント損失が発生する可能性がある場所と理由について質問しました。質問は、誰かが彼女のブログ投稿の1つに、showplan_xml
と主張していたコメントの結果でした。 XE Profilerによって、またはサーバーからのイベントの「ライブ」ストリームを介してイベントを収集することはできません。 UIにイベントを追加し、ライブデータを監視することで、本番ワークロードに対してpost_query_execution_showplanイベントを使用することによるパフォーマンスへの悪影響を日常的に示しているため、これが正しくないことがわかりました。これにより、より詳細な議論が始まりました。拡張イベントがデータ収集中に生成されたイベントをいつどのように破棄するかについて。
イベントサイズの問題
拡張イベントは、サーバーで最初に開始されたイベントセッションの内部メモリバッファースペースを構成します。イベントセッションオプションの構成により、メモリバッファーのサイズと、イベントセッションが収集できるイベントの最大サイズが決まります。拡張イベントによって生成されるほとんどのイベントは比較的軽量でバイナリ形式では小さいですが、特定のイベントは、バッファリングする必要のあるデータのはるかに大きなペイロードを生成する可能性があります。デフォルトのイベントセッションオプションは、サイズが1,441,587バイトのイベントを保持するための3つの内部メモリバッファを備えたセッション構成になります。イベントセッションのメモリバッファのサイズと数は、サーバー上のセッションSTATE=STARTの間にsys.dm_xe_sessionsDMVで確認できます。
SELECT s.name、s.total_regular_buffers、s.regular_buffer_size、s.total_large_buffers、s.large_buffer_size、s.total_buffer_sizeFROM sys.dm_xe_sessions AS s;
システム定義のイベントセッションごとに大きなバッファーがゼロであり、大きなバッファーサイズもデフォルト構成であるゼロに設定されていることに注意してください。イベントセッションのラージバッファは、イベントセッションにMAX_EVENT_SIZEセッションオプションが設定されている場合にのみ作成されます。このオプションのデフォルト値は0です。これは、イベントセッションが実際に消費できる最大のイベントが、通常のメモリバッファーのサイズである1,441,587バイトであることを意味します。 showplan_xmlを生成するイベントなど、特定のイベントの場合、実際には、イベントセッションのデフォルトのメモリバッファサイズよりも大きいイベントサイズを設定するのは比較的簡単です。このような場合、大きなイベントは、ディスパッチするためにメモリバッファに配置できないため、実際にはイベントセッションによって破棄されます。
イベント損失の制御
イベントセッションが実際に収集できるイベントの大きさを決定する3つの特定のセッションオプションと、イベントセッションのバッファメモリがいっぱいまたはプレッシャーがかかっているときにイベントをドロップする方法を制御するオプションがあります。大きなイベントペイロードを生成する可能性のあるイベントの収集について話しているとき、これら4つすべてが重要であり、イベントをドロップする可能性を最小限に抑えたいと考えています。イベントセッションのバッファスペースのメモリ不足によりイベントが失われる傾向があるイベントセッションの例を以下に示します。
CREATE EVENT SESSION [Locks] ON SERVER ADD EVENT sqlserver.lock_acquired、ADD EVENT sqlserver.lock_releasedADD TARGET package0.event_file(SET filename =N'Locks'、max_file_size =(5)、max_rollover_files =(4))WITH(MAX_MEMORY =4096 KB、MEMORY_PARTITION_MODE =NONE、EVENT_RETENTION_MODE =ALLOW_SINGLE_EVENT_LOSS、MAX_EVENT_SIZE =0 KB);
注:これは、本番ワークロードで実行することをお勧めするイベントセッションではありません。すべてのロックの取得と解放を追跡しているため、生成されるデータの量は膨大になります。
このセッションを開始してから、ブログで利用可能なAdventureWorks BooksOnlineワークロードジェネレーターをSQLServerのインスタンスに対して実行すると、イベントの生成が速く、event_fileターゲットへのバッファーフラッシュが遅れるため、セッションはイベントのドロップを急速に開始します。構成されています。イベントセッションオプションがEVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSSで構成されている場合、イベントセッションによってドロップされたイベントの数はsys.dm_xe_sessionsDMVで追跡できます。イベントセッションがEVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSSで構成されている場合、イベントのメモリバッファー全体をドロップでき、ドロップされたバッファーの数のみがカウントされ、各バッファーに含まれる個々のイベントの数はカウントされません。
SELECT s.name、s.total_regular_buffers、s.regular_buffer_size、s.total_large_buffers、s.large_buffer_size、s.dropped_event_count、s.dropped_buffer_count、s.largest_event_dropped_sizeFROM sys.dm_xe_sessions AS s;
ここでは、100,521個のイベントがドロップされ、ドロップされたイベントの最大サイズは176バイトであり、通常のバッファースペースのサイズよりも小さいため、通常のバッファーメモリスペースの負荷に達していることがわかります。ただし、2つのshowplanイベントを収集するイベントセッションを作成する場合(これがパフォーマンスに深刻な悪影響を及ぼし、本番サーバーで実行すべきではない理由については、この記事を参照してください)、バッチの開始イベントと完了イベントとともに、より大きなイベントを生成します計画では、イベントのサイズが原因でイベントの損失を引き起こす可能性があります。
CREATE EVENT SESSION [DropsEvents] ON SERVER ADD EVENT sqlserver.query_post_execution_showplan、ADD EVENT sqlserver.query_pre_execution_showplan、ADD EVENT sqlserver.sql_batch_completed、ADD EVENT sqlserver.sql_batch_starting;
ここでは、largest_event_dropped_sizeがregular_buffer_sizeよりも大きいことがわかります。これは、セッションバッファーの構成を変更する必要があることを意味します。イベントセッションのMAX_MEMORYを増やすと、通常のバッファーのサイズが増える可能性があります。デフォルト値はわずか4MBです。これは、上記の1.4MBのバッファサイズの元になります。イベントセッションでこれを64MBに変更すると、regular_buffer_sizeのサイズは22.4MBになり、3.7MBのドロップイベントに対応します。もう1つのオプションは、MAX_EVENT_SIZEオプションを設定することです。これは、大きなイベントにlarge_buffer_sizeを提供し、セッションに2で割られます。
CREATE EVENT SESSION [CollectsEvents] ON SERVER ADD EVENT sqlserver.query_post_execution_showplan、ADD EVENT sqlserver.query_pre_execution_showplan、ADD EVENT sqlserver.sql_batch_completed、ADD EVENT sqlserver.sql_batch_startingWITH(MAX_MEMORY =65536
したがって、ここでは33.6MBサイズの2つの大きなバッファーを確認できます。同じプランを再度実行した後、新しいCollectsEventsセッションのドロップイベントはありませんが、デフォルトを使用してDropsEventsセッションのドロップイベントを2倍にしました。
だから、あなたはそれを持っています。イベントセッションで特定のイベントが収集されない理由、イベントがドロップされたときのトラブルシューティングの方法、および問題の原因となっているのがイベントのサイズであるかどうかを判断する方法。クライアントシステムで実際に使用されているセッションの多くには、特にメモリに関しては、イベントセッションオプションのデフォルトがあります。これは、拡張イベントで使用されるバッファリングメカニズムを理解し、生成される可能性のあるイベントのサイズを検討した後、イベントの可能性を最小限に抑えるためにセッションオプションの定義方法を変更し始める1つの領域です。メモリスペースの制限またはイベントサイズの制約のために削除されます。