拡張イベントのターゲット

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

この記事では、拡張イベントターゲットを使用するタイミングと方法について説明します。 各ターゲットについて次のことを説明します。

  • イベントによって送信されるデータを収集およびレポートする の機能。
  • パラメータ、説明が不要なパラメータの場合を除きます

次の表では、異なるデータベース エンジンにおける各ターゲットの種類の可用性について説明します。

ターゲットの型 SQL Server Azure SQL Database Azure SQL Managed Instance
etw_classic_sync_target はい No いいえ
event_counter はい イエス はい
event_file はい イエス はい
event_stream はい イエス はい
histogram はい イエス はい
pair_matching はい No いいえ
ring_buffer はい イエス はい

前提条件

この記事を最大限に活用するには、次の操作を行う必要があります。

パラメーター、アクション、フィールド

拡張イベントの中心になるのは CREATE EVENT SESSION ステートメントです。 ステートメントを記述するには、次のものが必要です。

  • セッションに追加するイベント
  • それぞれの選択したイベントに関連付けられているフィールド。
  • セッションに追加する各ターゲットに関連付けられているパラメーター

システム ビューからこのようなリストを返す SELECT ステートメントは、次の記事のセクション C からコピーできます。

実際 CREATE EVENT SESSION のステートメントのコンテキストで使用されるパラメーター、フィールド、およびアクションは、セクション B2 (T-SQL の観点) から確認できます。

etw_classic_sync_target ターゲット

SQL Server の拡張イベントは、Windows イベント トレーシング(ETW) と連携してシステムの使用状況を監視できます。 詳細については、以下を参照してください:

この ETW ターゲットは受信したデータを 同期的 に処理しますが、ほとんどのターゲットは 非同期的に処理します。

Note

Azure SQL Managed Instance および Azure SQL Database では、etw_classic_sync_target ターゲットはサポートされていません。 別の方法として、Azure Storage に event_file 格納されている BLOB でターゲットを使用します。

event_counter ターゲット

event_counter ターゲットを使うと、特定のイベントが発生した回数をカウントできます。

他のほとんどのターゲットとは次の点が異なります。

  • ターゲットには event_counter パラメーターがありません。
  • event_counter ターゲットは、受信したデータを 同期的に処理します。

event_counter 目標によってキャプチャされる出力の例

package_name   event_name         count
------------   ----------         -----
sqlserver      checkpoint_begin   4

次に、前の CREATE EVENT SESSION 結果を返したステートメントを示します。 この例では、カウントが package0.counter 4 に達した後にカウントを 停止するために、WHERE 句述語でフィールドを使用しました。

CREATE EVENT SESSION [event_counter_1]
    ON SERVER
    ADD EVENT sqlserver.checkpoint_begin   -- Test by issuing CHECKPOINT; statements.
    (
        WHERE [package0].[counter] <= 4   -- A predicate filter.
    )
    ADD TARGET package0.event_counter
    WITH
    (
        MAX_MEMORY = 4096 KB,
        MAX_DISPATCH_LATENCY = 3 SECONDS
    );

event_file ターゲット

event_file ターゲットは 、バッファーからディスク ファイルまたは Azure Storage 内の BLOB にイベント セッション出力を書き込みます。

  • filename 句で ADD TARGET パラメーターを指定します。 ファイル名の拡張子は xel にする必要があります。
  • 指定したファイル名をプレフィックスとして使用し、その後に日時に基づく長い整数と、xel 拡張子が付加されます。

Note

Azure SQL Managed Instance と Azure SQL Database は、filename パラメーターの値として Azure Storage 内の BLOB のみ。

特に SQL Database (または SQL Managed Instance) の event_file コード例については、「SQL Database の拡張イベント用のイベント ファイル ターゲット コード」に関するページを参照してください。

CREATE EVENT SESSION と event_file ターゲット

ADD TARGET ターゲットを追加する event_file 句の CREATE EVENT SESSION 例を次に示します。

CREATE EVENT SESSION [locks_acq_rel_eventfile_22]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET
            collect_database_name=(1),
            collect_resource_description=(1)
        ACTION (sqlserver.sql_text,sqlserver.transaction_id)
        WHERE
        (
            [database_name]=N'InMemTest2'
            AND
            [object_id]=370100359
        )
    ),
    ADD EVENT sqlserver.lock_released
    (
        SET
            collect_database_name=1,
            collect_resource_description=1
        ACTION(sqlserver.sql_text,sqlserver.transaction_id)
        WHERE
        (
            [database_name]=N'InMemTest2'
            AND
            [object_id]=370100359
        )
    )
    ADD TARGET package0.event_counter,
    ADD TARGET package0.event_file
    (
        SET filename=N'C:\temp\locks_acq_rel_eventfile_22-.xel'
    )
    WITH
    (
        MAX_MEMORY=4096 KB,
        MAX_DISPATCH_LATENCY=10 SECONDS
    );

sys.fn_xe_file_target_read_file() 関数

event_file ターゲットは、人間が読むことのできないバイナリ形式で、受信したデータを格納します。 sys.fn_xe_file_target_read_file関数を使用すると、ファイルの内容を xel リレーショナル行セットとして表すことができます。

SQL Server 2016 以降のバージョンでは、次の例のような SELECT ステートメントを使用します。

SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file(
    'C:\temp\locks_acq_rel_eventfile_22-*.xel', NULL, NULL, NULL)  AS f;

SQL Server 2014 の場合は、次の 例のようなSELECT ステートメントを使用します。 SQL Server 2014 以降では、xem ファイルは使われなくなっています。

SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file(
    'C:\temp\locks_acq_rel_eventfile_22-*.xel', 'C:\temp\metafile.xem', NULL, NULL) AS f;

どちらの例でも、* ワイルドカードは、指定したプレフィックスで始まるすべての xel ファイルを読み取るために使用されます。

Azure SQL Database では、sys.fn_xe_file_target_read_file() BLOB を含むコンテナーに対する List アクセス許可を持つ Read SAS トークンを含むデータベース スコープの資格情報を作成した後、xel 関数を呼び出すことができます。

/*
Create a master key to protect the secret of the credential
*/
IF NOT EXISTS (
    SELECT 1
    FROM sys.symmetric_keys
    WHERE name = '##MS_DatabaseMasterKey##'
)
CREATE MASTER KEY;

/*
(Re-)create a database scoped credential.
The name of the credential must match the URI of the blob container.
*/
IF EXISTS (
    SELECT *
    FROM sys.database_credentials
    WHERE name = 'https://exampleaccount4xe.blob.core.windows.net/extended-events-container'
)
DROP DATABASE SCOPED CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container];

/*
The secret is the SAS token for the container. The Read and List permissions are set.
*/
CREATE DATABASE SCOPED CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
        SECRET = 'sp=rl&st=2023-10-09T22:12:54Z&se=2023-10-10T06:12:54Z&spr=https&sv=2022-11-02&sr=c&sig=REDACTED';

/*
Return event session data
*/
SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file('https://exampleaccount4xe.blob.core.windows.net/extended-events-container/event-session-1', DEFAULT, DEFAULT, DEFAULT) AS f;

Azure SQL Managed Instance では、xelBLOB を含むコンテナーに対するsys.fn_xe_file_target_read_file()アクセス許可を持つRead SAS トークンを含むサーバー資格情報を作成した後で、List関数を呼び出すことができます。

IF NOT EXISTS (
    SELECT 1
    FROM sys.symmetric_keys
    WHERE name = '##MS_DatabaseMasterKey##'
)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'REDACTED';

/*
(Re-)create a database scoped credential.
The name of the credential must match the URI of the blob container.
*/
IF EXISTS (
    SELECT *
    FROM sys.credentials
    WHERE name = 'https://exampleaccount4xe.blob.core.windows.net/extended-events-container'
)
DROP CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container];

/*
The secret is the SAS token for the container. The Read and List permissions are set.
*/
CREATE CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
        SECRET = 'sp=rl&st=2023-10-09T22:12:54Z&se=2023-10-10T06:12:54Z&spr=https&sv=2022-11-02&sr=c&sig=REDACTED';

/*
Return event session data
*/
SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file('https://exampleaccount4xe.blob.core.windows.net/extended-events-container/event-session-1', DEFAULT, DEFAULT, DEFAULT) AS f;

ヒント

最初の引数 に完全な BLOB 名の代わりに BLOB 名プレフィックスを指定すると、sys.fn_xe_file_target_read_file() 関数はプレフィックスに一致するコンテナー内のすべての BLOB からデータを返します。 これにより、Azure Storage ではサポートされていない * ワイルドカードを使用せずに、特定のイベント セッションのすべてのロールオーバー ファイルからデータを取得できます。

前の Azure SQL の例では、xel 名前付きセッションのすべてのロールオーバー ファイルを読み取る event-session-1 拡張機能を省略しています。

event_file ターゲットに格納されているデータ

これは、SQL Server 2016 (13.x) 以降の sys.fn_xe_file_target_read_file バージョンから返されるデータの例です。

module_guid                            package_guid                           object_name     event_data                                                                                                                                                                                                                                                                                          file_name                                                      file_offset
-----------                            ------------                           -----------     ----------                                                                                                                                                                                                                                                                                          ---------                                                      -----------
D5149520-6282-11DE-8A39-0800200C9A66   03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2   lock_acquired   <event name="lock_acquired" package="sqlserver" timestamp="2016-08-07T20:13:35.827Z"><action name="transaction_id" package="sqlserver"><value>39194</value></action><action name="sql_text" package="sqlserver"><value><![CDATA[  select top 1 * from dbo.T_Target;  ]]></value></action></event>   C:\temp\locks_acq_rel_eventfile_22-_0_131150744126230000.xel   11776
D5149520-6282-11DE-8A39-0800200C9A66   03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2   lock_released   <event name="lock_released" package="sqlserver" timestamp="2016-08-07T20:13:35.832Z"><action name="transaction_id" package="sqlserver"><value>39194</value></action><action name="sql_text" package="sqlserver"><value><![CDATA[  select top 1 * from dbo.T_Target;  ]]></value></action></event>   C:\temp\locks_acq_rel_eventfile_22-_0_131150744126230000.xel   11776

histogram ターゲット

histogram ターゲットができるのは

  • 複数の項目の発生を個別にカウントすることです。
  • 異なる種類の項目の発生をカウントする。
    • [Event fields] (イベントのフィールド)
    • アクション

histogram ターゲットは、受信したデータを 同期的に処理します。

source_type パラメーターは、ヒストグラムターゲットを制御するためのキーです。

  • イベント フィールドのデータを source_type=0 収集します。
  • アクションのデータを source_type=1 収集します。 これが既定です。

slots パラメーターの既定値は 256 です。 別の値を割り当てると、値は次の 2 の累乗に切り上げられます。 たとえば、slots=59 は 64 まで切り上げられます。 histogram ターゲットのヒストグラム スロット の最大数は 16384 です。

ターゲットとして histogram コマンドを使うときに、予期しない結果が表示されることがあります。 一部のイベントは予想されるスロットに表示されない場合があります。一方、他のスロットでは、イベントの数が予想よりも多い場合があります。

これは、スロットにイベントを割り当てるときにハッシュ競合が発生した場合に発生する可能性があります。 これはまれですが、ハッシュ競合が発生した場合、あるスロットでカウントする必要があるイベントが別のスロットでカウントされます。 このため、特定のスロットの数が 0 と表示されるだけでイベントが発生しなかった場合は注意が必要です。

ここでは、次のシナリオを例に説明します。

  • histogram ターゲットとしてヒストグラムを使用し、 ごとにグループ化して拡張イベント セッションを設定し、ストアド プロシージャの実行を object_id 収集します。
  • ストアド プロシージャ A を実行してから、ストアド プロシージャ B を実行します。

両方の object_id ストアドプロシージャのハッシュ関数が同じ値を返した場合、ヒストグラムはストアドプロシージャ A が 2 回実行されていることを示し、ストアドプロシージャ B は表示されません。

個別の値の数が比較的少ない場合にこの問題を軽減するには、ヒストグラム スロットの数を予想される個別の値の二乗よりも大きく設定します。 たとえば、histogram ターゲットが source イベント フィールドに table_name 設定されていて、データベースに 20 個のテーブルがある場合、20*20 = 400 になります。 400 を超える 2 の次の累乗は 512 です。これは、この例で推奨されるスロット数です。

アクションを含むヒストグラム ターゲット

その ADD TARGET ... (SET ...) 句では、次 CREATE EVENT SESSION のステートメントでターゲット パラメーターの割り当て source_type=1 を指定します。 これは、ヒストグラムターゲットがアクションを追跡することを意味します。

この例では、ADD EVENT ... (ACTION ...) 句は sqlos.system_thread_id というターゲットの 1 つのアクションだけを提供します。 この ADD TARGET ... (SET ...) 句では、source=N'sqlos.system_thread_id' 割り当てが 表示されます。

Note

イベント セッションごとに同じ型 の複数のターゲットを追加することはできません。 これには histogram ターゲットが含まれます。 また、histogram ターゲットごとに複数のソース (アクションまたはイベント フィールド) を含めることはできません。 そのため、histogram 別個のターゲットで追加のアクション (またはイベント) フィールドを追跡するには、新しいイベント セッションが必要です。

CREATE EVENT SESSION [histogram_lockacquired]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
        (
        ACTION
            (
            sqlos.system_thread_id
            )
        )
    ADD TARGET package0.histogram
        (
        SET
            filtering_event_name=N'sqlserver.lock_acquired',
            slots=16,
            source=N'sqlos.system_thread_id',
            source_type=1
        );

キャプチャされたデータを次に示します。 value 列の system_thread_id 値は値です。 たとえば、全部で 236 個のロックがスレッド 6540 で取得されました。

value   count
-----   -----
 6540     236
 9308      91
 9668      74
10144      49
 5244      44
 2396      28

使用可能なアクションを検出するための SELECT

C.3SELECT ステートメントは、CREATE EVENT SESSION ステートメントで指定できるシステムが提供するアクションを取得できます。 WHERE 句で、o.name LIKE フィルターを編集して目的のアクションを指定します。

C.3 の SELECT で返される行セットの例を次に示します。 system_thread_id アクションは 2 行目にあります。

Package-Name   Action-Name                 Action-Description
------------   -----------                 ------------------
package0       collect_current_thread_id   Collect the current Windows thread ID
sqlos          system_thread_id            Collect current system thread ID
sqlserver      create_dump_all_threads     Create mini dump including all threads
sqlserver      create_dump_single_thread   Create mini dump for the current thread

イベント フィールドを含むヒストグラム ターゲット

次の例では、source_type=0が設定されます。 source に割り当てられる値はイベント フィールドです。

CREATE EVENT SESSION [histogram_checkpoint_dbid]
    ON SERVER
    ADD EVENT  sqlserver.checkpoint_begin
    ADD TARGET package0.histogram
    (
    SET
        filtering_event_name = N'sqlserver.checkpoint_begin',
        source               = N'database_id',
        source_type          = 0
    );

histogram ターゲットでは次のようなデータがキャプチャされます。 このデータは、ID=5 のデータベースで checkpoint_begin イベントが 7 回発生したことを示しています。

value   count
-----   -----
5       7
7       4
6       3

選択したイベントで使用可能なフィールドを検出する SELECT

C.4SELECT の ステートメントでは、選択できるイベント フィールドが示されます。 最初に、o.name LIKE フィルターを編集して選択するイベント名を指定します。

C.4 SELECT からは次のような行セットが返されます。 この行セットでは、checkpoint_begin イベントが histogram ターゲットに提供できるフィールドは database_id の 1 つのみであることがわかります。

Package-Name   Event-Name         Field-Name   Field-Description
------------   ----------         ----------   -----------------
sqlserver      checkpoint_begin   database_id  NULL
sqlserver      checkpoint_end     database_id  NULL

pair_matching ターゲット

pair_matching ターゲットを使用すると、対応する終了イベントのない開始イベントを検出できます。 たとえば、lock_acquired イベントが発生した後に適切なタイミングで対応する lock_released イベントが発生しないと、問題になる可能性があります。

システムで開始イベントと終了イベントが自動的にマッチングされることはありません。 代わりに、開発者が CREATE EVENT SESSION ステートメントでシステムにマッチングを示す必要があります。 開始イベントと終了イベントがマッチングする場合、ペアは破棄されるので、マッチングしていない開始イベントに注目できます。

開始イベントと終了イベントのペアのマッチングが可能なフィールドの検索

C.4 SELECT を使用することで、次の行セットには lock_acquired イベントの対象になるフィールドが約 16 個あることがわかります。 ここで示されている行セットは、マッチングするフィールドがわかるように手動で分割されています。 duration などの一部のフィールドでは、照合を試みるのは無意味です。

Package-Name   Event-Name   Field-Name               Field-Description
------------   ----------   ----------               -----------------
sqlserver   lock_acquired   database_name            NULL
sqlserver   lock_acquired   mode                     NULL
sqlserver   lock_acquired   resource_0               The ID of the locked object, when lock_resource_type is OBJECT.
sqlserver   lock_acquired   resource_1               NULL
sqlserver   lock_acquired   resource_2               The ID of the lock partition, when lock_resource_type is OBJECT, and resource_1 is 0.
sqlserver   lock_acquired   transaction_id           NULL

sqlserver   lock_acquired   associated_object_id     The ID of the object that requested the lock that was acquired.
sqlserver   lock_acquired   database_id              NULL
sqlserver   lock_acquired   duration                 The time (in microseconds) between when the lock was requested and when it was canceled.
sqlserver   lock_acquired   lockspace_nest_id        NULL
sqlserver   lock_acquired   lockspace_sub_id         NULL
sqlserver   lock_acquired   lockspace_workspace_id   NULL
sqlserver   lock_acquired   object_id                The ID of the locked object, when lock_resource_type is OBJECT. For other lock resource types it will be 0
sqlserver   lock_acquired   owner_type               NULL
sqlserver   lock_acquired   resource_description     The description of the lock resource. The description depends on the type of lock. This is the same value as the resource_description column in the sys.dm_tran_locks view.
sqlserver   lock_acquired   resource_type            NULL

pair_matching ターゲットの例

次の CREATE EVENT SESSION ステートメントでは、2 つのイベントと 2 つのターゲットが指定されています。 pair_matching ターゲットでは、イベントをペアにするために 2 つのフィールド セットが指定されています。 begin_matching_columns に割り当てられたコンマ区切りフィールドのシーケンス と end_matching_columns は同じである必要があります。 コンマ区切り値で示されるフィールドの間にタブや改行文字があってはなりませんが、スペースは許されます。

結果を絞り込むため、最初に sys.objects からテスト テーブルの object_id を検索して選択しました。 ADD EVENT ... (WHERE ...) 句にその 1 つのオブジェクト ID のフィルターを追加しました。

CREATE EVENT SESSION [pair_matching_lock_a_r_33]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET
            collect_database_name = 1,
            collect_resource_description = 1
        ACTION (sqlserver.transaction_id)
        WHERE
        (
            [database_name] = 'InMemTest2'
            AND
            [object_id] = 370100359
        )
    ),
    ADD EVENT sqlserver.lock_released
    (
        SET
            collect_database_name = 1,
            collect_resource_description = 1
        ACTION (sqlserver.transaction_id)
        WHERE
        (
            [database_name] = 'InMemTest2'
            AND
            [object_id] = 370100359
        )
    )
    ADD TARGET package0.event_counter,
    ADD TARGET package0.pair_matching
    (
        SET
            begin_event = N'sqlserver.lock_acquired',
            begin_matching_columns =
                N'resource_0, resource_1, resource_2, transaction_id, database_id',
            end_event = N'sqlserver.lock_released',
            end_matching_columns =
                N'resource_0, resource_1, resource_2, transaction_id, database_id',
            respond_to_memory_pressure = 1
    )
    WITH
    (
        MAX_MEMORY = 8192 KB,
        MAX_DISPATCH_LATENCY = 15 SECONDS
    );

イベント セッションをテストするため、意図的に、取得した 2 つのロックが解放されないようにしています。 次のような T-SQL 手順を使用しました。

  1. BEGIN TRANSACTION
  2. UPDATE MyTable...
  3. ターゲットを調べるまで、意図的に aCOMMIT TRANSACTION を発行しません。
  4. 後でテストした後、COMMIT TRANSACTION を発行しました。

簡単な event_counter ターゲットでは次のような出力行が得られました。 52-50=2 であるため、この出力からは、pair-matching ターゲットからの出力を調べるときにペアになっていない 2 つの lock_acquired イベントが表示されることになります。

package_name   event_name      count
------------   ----------      -----
sqlserver      lock_acquired   52
sqlserver      lock_released   50

pair_matching の出力は次のとおりです。 event_counter 出力で提案されているように、2 つの lock_acquired 行が実際に表示されます。 これら 2 つの lock_acquired イベントはペアになっていません。

package_name   event_name      timestamp                     database_name   duration   mode   object_id   owner_type   resource_0   resource_1   resource_2   resource_description   resource_type   transaction_id
------------   ----------      ---------                     -------------   --------   ----   ---------   ----------   ----------   ----------   ----------   --------------------   -------------   --------------
sqlserver      lock_acquired   2016-08-05 12:45:47.9980000   InMemTest2      0          S      370100359   Transaction  370100359    3            0            [INDEX_OPERATION]      OBJECT          34126
sqlserver      lock_acquired   2016-08-05 12:45:47.9980000   InMemTest2      0          IX     370100359   Transaction  370100359    0            0                                   OBJECT          34126

ペアになっていない lock_acquired イベントの行には、sqlserver.sql_text アクションによって提供される T-SQL テキストを 含めることができます。 これにより、ロックを取得したクエリがキャプチャされます。

ring_buffer ターゲット

ring_buffer ターゲットはメモリ内での迅速かつ簡単なイベント収集にのみ便利です。 イベント セッションを停止すると、格納されている出力は破棄されます。

この セクションでは、XQuery を使用して、リングバッファの内容の XML 表現をより読みやすいリレーショナル行セットに変換する方法についても説明します。

ヒント

ring_buffer ターゲットを追加するときは、MAX_MEMORY パラメーターを1024 KB 以下に設定します。 値を大きくすると、メモリ消費量が不必要に増加する可能性があります。

既定では、 MAX_MEMORYring_bufferターゲットは SQL Server では制限されず、Azure SQL Database と Azure SQL Managed Instance では 32 MB (メガバイト)に制限されます。

次の 例に示すように、ring_buffer ターゲットから XML に変換してデータを使用します。 この変換中に、4 MB (メガバイト) XML ドキュメントに収まらないデータはすべて省略されます。 したがって、より大きな MAX_MEMORY 値を使用して(またはこのパラメータをデフォルト値のままにして)リング・バッファに多くのイベントをキャプチャしても、XML マークアップと Unicode 文字列のオーバーヘッドを考慮すると、XML ドキュメントのサイズに4 MB の制限があるため、すべてのイベントを消費できない可能性があります。

XML ドキュメント内の truncated 属性が次に示すように 1 に設定されている場合、XML への変換中にリング バッファーの内容が省略されることがわかります。

<RingBufferTarget truncated="1" processingTime="0" totalEventsProcessed="284" eventCount="284" droppedCount="0" memoryUsed="64139">

CREATE EVENT SESSION と ring_buffer ターゲット

ring_buffer ターゲットとのイベント セッションを作成する例を次に示します。 この例では、MAX_MEMORY パラメーターは 2 回表示されます。1 回は ring_buffer ターゲット メモリを 1024 KB (キロバイト)に設定し、1 回はイベント セッション バッファー メモリを 2 MB (メガバイト)に設定します。

CREATE EVENT SESSION [ring_buffer_lock_acquired_4]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET collect_resource_description=(1)
        ACTION(sqlserver.database_name)
        WHERE
        (
            [object_id]=(370100359)  -- ID of MyTable
            AND
            sqlserver.database_name='InMemTest2'
        )
    )
    ADD TARGET package0.ring_buffer
    (
        SET MAX_EVENTS_LIMIT = 98,
            MAX_MEMORY = 1024
    )
    WITH
    (
        MAX_MEMORY = 2 MB,
        MAX_DISPATCH_LATENCY = 3 SECONDS
    );

ring_buffer ターゲットが受け取る lock_acquired に関する XML 形式の出力

SELECT ステートメントによって取得されると、リング バッファーの内容が XML ドキュメントとして表示されます。 次に例を示します。 ただし、簡潔にするために、2 つ以外のすべての <event> 要素が削除されました。 さらに、個々の <event> セクション内でも、いくつかの <data> 要素が削除されています。

<RingBufferTarget truncated="0" processingTime="0" totalEventsProcessed="6" eventCount="6" droppedCount="0" memoryUsed="1032">
  <event name="lock_acquired" package="sqlserver" timestamp="2016-08-05T23:59:53.987Z">
    <data name="mode">
      <type name="lock_mode" package="sqlserver"></type>
      <value>1</value>
      <text><![CDATA[SCH_S]]></text>
    </data>
    <data name="transaction_id">
      <type name="int64" package="package0"></type>
      <value>111030</value>
    </data>
    <data name="database_id">
      <type name="uint32" package="package0"></type>
      <value>5</value>
    </data>
    <data name="resource_0">
      <type name="uint32" package="package0"></type>
      <value>370100359</value>
    </data>
    <data name="resource_1">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="resource_2">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="database_name">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[]]></value>
    </data>
    <action name="database_name" package="sqlserver">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[InMemTest2]]></value>
    </action>
  </event>
  <event name="lock_acquired" package="sqlserver" timestamp="2016-08-05T23:59:56.012Z">
    <data name="mode">
      <type name="lock_mode" package="sqlserver"></type>
      <value>1</value>
      <text><![CDATA[SCH_S]]></text>
    </data>
    <data name="transaction_id">
      <type name="int64" package="package0"></type>
      <value>111039</value>
    </data>
    <data name="database_id">
      <type name="uint32" package="package0"></type>
      <value>5</value>
    </data>
    <data name="resource_0">
      <type name="uint32" package="package0"></type>
      <value>370100359</value>
    </data>
    <data name="resource_1">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="resource_2">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="database_name">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[]]></value>
    </data>
    <action name="database_name" package="sqlserver">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[InMemTest2]]></value>
    </action>
  </event>
</RingBufferTarget>

上の XML を取得するには、イベント セッションがアクティブになっている間に次の SELECT を発行します。 XML データが、システム ビュー sys.dm_xe_session_targets から取得されます。

SELECT CAST(LocksAcquired.TargetXml AS XML) AS RBufXml
INTO #XmlAsTable
FROM (
    SELECT CAST(t.target_data AS XML) AS TargetXml
    FROM sys.dm_xe_session_targets AS t
    INNER JOIN sys.dm_xe_sessions AS s
        ON s.address = t.event_session_address
    WHERE t.target_name = 'ring_buffer'
        AND s.name = 'ring_buffer_lock_acquired_4'
) AS LocksAcquired;

SELECT *
FROM #XmlAsTable;

XML を行セットとして表示するための XQuery

上の XML をリレーショナル行セットとして表示するには、上の SELECT ステートメントに続けて次の T-SQL ステートメントを発行します。 コメントの付いた行では、各 XQuery の使用方法が説明されています。

SELECT
    -- (A)
    ObjectLocks.value('(@timestamp)[1]', 'datetime') AS [OccurredDtTm],
    -- (B)
    ObjectLocks.value('(data[@name="mode"]/text)[1]', 'nvarchar(32)') AS [Mode],
    -- (C)
    ObjectLocks.value('(data[@name="transaction_id"]/value)[1]', 'bigint') AS [TxnId],
    -- (D)
    ObjectLocks.value('(action[@name="database_name" and @package="sqlserver"]/value)[1]', 'nvarchar(128)') AS [DatabaseName]
FROM #XmlAsTable
CROSS APPLY
    -- (E)
    TargetDateAsXml.nodes('/RingBufferTarget/event[@name="lock_acquired"]') AS T(ObjectLocks);

前の SELECT で使用されている XQuery に関するメモ

(A)

  • イベント <event> 要素での属性の値。
  • '(...)[1]' コンストラクトは、XMLデータ型変数と列の .value() XQueryメソッドの要件である反復ごとに 1 つの値のみが返されることを保証します。

(B)

  • name 属性が <text> と等しいセクション <data> 要素内のセクション mode 要素の内部値

(C)

  • name 属性が <value> と等しいセクション <data> 要素内のセクション transaction_id 要素の内部値

(D)

  • <event> には、<action> が含まれます。
  • <action> name= 属性が database_name と等しく、package= 属性が sqlserver と等しい(または package0 と等しくない)セクション <value> 要素の内部値

(E)

  • CROSS APPLY に等しい <event> 属性を持つ個々の name 要素ごとに lock_acquired は処理を繰り返します
  • これは、上の FROM 句から返された XML に対して行われます。

XQuery SELECT からの出力

次に示すのは、前の XQuery を含む T-SQL によって生成された行セットです。

OccurredDtTm              Mode    DatabaseName
------------              ----    ------------
2016-08-05 23:59:53.987   SCH_S   InMemTest2
2016-08-05 23:59:56.013   SCH_S   InMemTest2

event_stream ターゲット

event_stream ターゲットは、C# などの言語で記述された .NET プログラムでのみ使用できます。 C# やその他の .NET 開発者は、System.Diagnostics Microsoft.SqlServer.XEvents.Linq 名前空間の.NET Framework クラスを通じてイベントストリームにアクセスできます。 このターゲットは T-SQL では使用できません。

The event data stream was disconnected because there were too many outstanding events. To avoid this error either remove events or actions from your session or add a more restrictive predicate filter to your session. ターゲットから読み取るときに event_stream エラー 25726 が発生した場合は、イベントストリームがクライアントがデータを消費するよりも速くデータでいっぱいになったことを意味します。 これにより、データベース エンジンは、データベース エンジンのパフォーマンスに影響を与えないように、イベント ストリームから切断します。

XEvent の名前空間