分享方式:


擴充事件的目標

適用於:SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體

本文說明何時及如何使用擴充事件目標。 針對每個目標,現有文章說明︰

  • 其收集和報告事件傳送資料的能力
  • 其參數 (不需加以說明的參數除外)

下表描述了不同資料庫引擎中每個目標型別的可用性。

目標類型 SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體
etw_classic_sync_target No
event_counter Yes .是 Yes
event_file Yes .是 Yes
event_stream Yes .是 Yes
色階分佈圖 Yes .是 Yes
pair_matching No
ring_buffer Yes .是 Yes

必要條件

若要充分利用本文,您應:

參數、動作和欄位

CREATE EVENT SESSION 陳述式是擴充事件的重要部分。 若要撰寫陳述式,您需要以下各項:

  • 您想要新增至工作階段的事件
  • 與所每個選擇事件關聯的欄位
  • 與您想要新增至工作階段的每個目標關聯的參數

在下文第 C 節中,您可複製會從系統檢視表傳回這類清單的 SELECT 陳述式:

您可從區段 B2 (T-SQL 檢視方塊) 看到實際 CREATE EVENT SESSION 陳述式內容中使用的參數、欄位和動作。

etw_classic_sync_target 目標

在 SQL Server 中,擴充事件可與 Windows 事件追蹤 (ETW) 搭配運作,用於監視系統活動。 如需詳細資訊,請參閱

此 ETW 目標會同步處理其接收的資料,其中大部分目標則會非同步處理其接收的資料。

注意

Azure SQL 受控執行個體和 Azure SQL 資料庫不支援 etw_classic_sync_target 目標。 或者,將 event_file 目標與存放在 Azure 儲存體中的 Blob 搭配使用。

event_counter 目標

event_counter 目標會計算每個所指定事件的發生次數。

與大部分的其他目標不同︰

  • event_counter 目標沒有參數。
  • event_counter 目標會同步處理其接收的資料。

event_counter 目標擷取的範例輸出

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

接下來是傳回先前結果的 CREATE EVENT SESSION 陳述式。 在此範例中,WHERE 子句述詞中使用了 package0.counter 欄位,在計數達到 4 之後停止計數。

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 儲存體中的 Blob:

  • 您可以在 ADD TARGET 子句中指定 filename 參數。 副檔名必須是 xel
  • 系統會使用您選擇的檔案名稱作為附加日期時間型 long 整數的前置詞,並且後接 xel 副檔名。

注意

Azure SQL 受控執行個體 和 Azure SQL 資料庫只會將 Azure 儲存體中的 Blob 設定為 filename 參數的值。

如需 SQL Database 或 SQL 受控執行個體專屬的 event_file 程式碼範例,請參閱 SQL Database 中擴充事件的事件檔案目標程式碼

含 event_file 目標的 CREATE EVENT SESSION

以下是 CREATE EVENT SESSION 的範例,其中包含新增至 event_file 目標的 ADD TARGET 子句。

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 資料庫中,您可在建立資料庫範圍認證之後呼叫 sys.fn_xe_file_target_read_file() 函數,其中包含在具有 xel Blob 的容器上使用 ReadList 權限的 SAS 權杖:

/*
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 受控執行個體中,您可在建立資料庫範圍認證之後呼叫 sys.fn_xe_file_target_read_file() 函數,其中包含在具有 xel Blob 的容器上使用 ReadList 權限的 SAS 權杖:

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;

提示

如果您在 sys.fn_xe_file_target_read_file() 的第一個引數中指定 Blob 名稱前置詞,而不是完整的 Blob 名稱,則函數會從容器中符合前置詞的所有 Blob 中傳回資料。 這可讓您從指定事件工作階段的所有換用檔案中擷取資料,而不使用 Azure 儲存體不支援的 * 萬用字元。

之前的 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 目標會同步處理其接收的資料。

source_type 參數是控制色階分佈圖目標的關鍵:

  • source_type=0:收集事件欄位的資料。
  • source_type=1:收集動作的資料。 這是預設值。

slots 參數預設值為 256。 如果您指派另一個值,值會四捨五入至下一個 2 的次方。 例如,插槽=59 會四捨五入為 64。 histogram 目標的最大色階分佈圖插槽數目為 16384。

使用 histogram 做為目標時,您可能有時會看到非預期結果。 某些事件可能不會出現在預期插槽中,而其他插槽可能會顯示高於預期的事件計數。

如果在將事件指派給插槽時發生雜湊衝突,則可能會發生這種情況。 雖然這是罕見的,但如果發生雜湊衝突,則應在某個插槽中計數的事件會在另一個插槽中計數。 出於此原因,假設事件未發生只是因為特定插槽中的計數顯示為零,則應謹慎處理。

例如,請設想下列情境:

  • 您可以使用 histogram 為目標,並以 object_id 分組,藉此設定擴充事件工作階段,以收集預存程序執行。
  • 您可以執行預存程序 A。然後,執行預存程序 B。

如果雜湊函數針對這兩個預存程序的 object_id 傳回相同的值,則色階分佈圖會顯示預存程序 A 執行兩次,而且不會顯示預存程序 B。

若要在相異值數目相對較小時緩解此問題,請將色階分佈圖插槽的數目設定為高於預期相異值的平方。 例如,如果 histogram 目標已將其 source 設定為 table_name 事件字段,且資料庫中有 20 個資料表,則 20*20 = 400。 下一個大於 400 的等級是 512,這是此範例中建議的插槽數目。

具有動作的色階分佈圖目標

在其 ADD TARGET ... (SET ...) 子句中,下列 CREATE EVENT SESSION 陳述式會指定目標參數指派 source_type=1。 這表示色階分佈圖目標會追蹤動作。

在目前的範例中,ADD EVENT ... (ACTION ...) 子句只會提供一個動作供選擇,即 sqlos.system_thread_id。 在 ADD TARGET ... (SET ...) 子句中,我們看到指派 source=N'sqlos.system_thread_id'

注意

無法對每個事件工作階段,新增超過一個相同類型的目標。 這包括 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
        );

下列是所擷取的資料。 system_thread_id 資料行中的值為 value 值。 例如,在執行緒 6540 下已取得共 236 個鎖定。

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

SELECT 以探索可用的動作

C.3 SELECT 陳述式能夠找到系統可讓您在 CREATE EVENT SESSION 陳述式中指定的動作。 在 WHERE 子句中,您可以先編輯 o.name LIKE 篩選條件,以符合感興趣的動作。

接下來是 C.3 SELECT 傳回的範例資料列集。 在第二個資料列中會看到 system_thread_id 動作。

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 的資料庫遇到 7 個 checkpoint_begin 事件。

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

SELECT 以探索所選擇事件上的可用欄位

C.4 SELECT 陳述式顯示您可從中進行選擇的事件欄位。 您會先將 o.name LIKE 篩選編輯成所選擇的事件名稱。

下列是 C.4 SELECT 傳回的資料列集。 資料列集顯示 database_idcheckpoint_begin 事件上唯一可為 histogram 目標提供值的欄位。

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 陳述式指定兩個事件和兩個目標。 pair_matching 目標會指定兩組欄位,以讓這些事件成對。 指派給 begin_matching_columnsend_matching_columns 的一串逗號分隔欄位必須相同。 雖然允許使用空格,但是逗號分隔值中所提及的欄位之間不允許定位字元或換行字元。

為了縮小結果範圍,我們會先從 sys.objects 進行選取,以尋找測試資料表的 object_id。 我們在 ADD EVENT ... (WHERE ...) 子句中新增了該物件識別碼的篩選條件。

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
    );

為了測試事件工作階段,我們刻意避免釋出兩個擷取的鎖定。 做法是使用下列 T-SQL 步驟︰

  1. BEGIN TRANSACTION.
  2. UPDATE MyTable....
  3. 檢查目標之前,刻意不發出 COMMIT TRANSACTION
  4. 稍後在測試之後,發出 COMMIT TRANSACTION

簡單的 event_counter 目標提供下列輸出資料列。 因為 52-50=2,所以檢查成對目標的輸出時,從輸出結果可知,我們會看到 2 個不成對的 lock_acquired 事件。

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

pair_matching 目標提供下列輸出。 如 event_counter 輸出所建議,我們確實會看到這兩個 lock_acquired 資料列。 我們看到這些資料列表示,這兩個 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 或更少。 使用較大的值可能會不必要地增加記憶體使用量。

根據預設,ring_buffer 目標的 MAX_MEMORY 不會限制在 SQL Server 中,且在 Azure SQL 資料庫和 Azure SQL 受控執行個體中限制為 32 MB。

您可將資料轉換成 XML,以取用 ring_buffer 目標中的資料,如下列範例所示。 在此轉換期間,會省略任何不符合 4 MB XML 文件的資料。 因此,即使您使用較大的 MAX_MEMORY 值,來擷取通道緩衝區中的更多事件 (或將此參數保留為預設值),您可能也無法取用所有事件,因為 XML 檔大小有 4 MB 的限制,請考慮 XML 標記和 Unicode 字符串的額外負荷。

您知道,如果 XML 檔案中的 truncated 屬性設定為 1,則會在轉換成 XML 期間省略通道緩衝區的內容,例如:

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

含 ring_buffer 目標的 CREATE EVENT SESSION

以下是使用 ring_buffer 目標建立事件工作階段的範例。 在此範例中,MAX_MEMORY 參數會顯示兩次:一次將 ring_buffer 目標記憶體設定為 1024 KB,一次將事件工作階段緩衝區記憶體設定為 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 文件。 範例如下。 但是,為了簡潔起見,除了兩個 <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 當作關聯式資料列集查看,請發出下列 T-SQL,以從前一個 SELECT 陳述式繼續。 加上註解的行說明 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)

  • timestamp= 屬性的值,在 <event> 元素上。
  • '(...)[1]' 建構可確保每個反覆項目都只會傳回 1 個值,這是 XML 資料類型變數和資料行的 .value() 方法的必要限制。

(B)

  • <text> 元素內部值,在其 name=屬性等於 mode<data> 元素內。

(C)

  • <value> 元素內部值,在其 name= 屬性等於 <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 開發人員都可透過 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 命名空間