扩展事件的目标
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例
本文介绍何时以及如何使用扩展事件目标。 对于每个目标,本文介绍:
- 其收集和报告由事件发送的数据的能力
- 其参数(浅显易懂的参数除外)
下表描述了每个目标类型在不同数据库引擎中的可用性。
目标类型 | SQL Server | Azure SQL Database | Azure SQL 托管实例 |
---|---|---|---|
etw_classic_sync_target | 是 | 否 | 否 |
event_counter | 是 | 是 | 是 |
event_file | 是 | 是 | 是 |
event_stream | 是 | 是 | 是 |
histogram | 是 | 是 | 是 |
pair_matching | 是 | 否 | 否 |
ring_buffer | 是 | 是 | 是 |
先决条件
若要充分利用本文,应:
请对扩展事件的基础知识有一些了解,如快速入门:扩展事件中所述。
已安装了 SQL Server Management Studio (SSMS) 的最新版本。 有关详细信息,请参阅 下载 SQL Server Management Studio (SSMS)。
在 SSMS 中,知道如何在 对象资源管理器 中右键单击事件会话下的目标节点,以便轻松查看输出数据。
参数、操作和字段
CREATE EVENT SESSION 语句是扩展事件的中心所在。 若要编写该语句,需要以下各项:
- 要添加到会话的事件
- 与每个所选事件关联的字段
- 与要添加到会话的每个目标关联的参数
从系统视图返回此类列表的 SELECT 语句可从以下文章的 C 节中复制:
可从 B2 部分(T-SQL 透视)查看实际 CREATE EVENT SESSION
语句的上下文中使用的参数、字段和操作。
etw_classic_sync_target 目标
在 SQL Server 中,扩展事件可以和 Windows 事件跟踪 (ETW) 相互操作来监视系统活动。 有关详细信息,请参阅:
此 ETW 目标同步处理其接收的数据,而大多数目标则是异步处理。
注意
Azure SQL 托管实例和 Azure SQL 数据库不支持 etw_classic_sync_target
目标。 作为替代方法,可以使用具有存储在 Azure 存储中的 Blob 的 event_file
目标。
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
。 - 系统会将你选择的文件名用作基于日期时间的长整型的前缀,后接
xel
扩展名。
注意
Azure SQL 托管实例和 Azure SQL 数据库在 Azure 存储中仅 blob 为 filename
参数的值。
有关 SQL 数据库或 SQL 托管实例特定的 event_file
代码示例,请参阅 SQL 数据库中扩展事件的事件文件目标代码。
使用 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 数据库中,在创建包含对包含 xel
blob 的容器具有 Read
和 List
权限的 SAS 令牌的数据库范围凭据后,可以调用 sys.fn_xe_file_target_read_file()
函数:
/*
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 托管实例中,在创建包含对包含 xel
blob 的容器具有 Read
和 List
权限的 SAS 令牌的服务器凭据后,可以调用 sys.fn_xe_file_target_read_file()
函数:
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 的数据。 这样就可以从给定事件会话的所有滚动更新文件中检索数据,而无需使用 *
wild卡,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
目标可实现以下功能:
- 单独计数多个项的出现次数
- 计数不同类型的项的出现次数:
- 事件字段
- 操作
histogram
目标同步处理其接收的数据。
source_type
参数是控制 histogram 目标的关键:
source_type=0
:收集某个事件字段的数据。source_type=1
:收集某个操作的数据。 这是默认情况。
“slots
”参数默认值为 256。 如果指定另一个值,该值将四舍五入为下一个 2 的幂。 例如,slots=59 四舍五入为 64。 histogram
目标的最大直方图槽数量为 16384。
使用 histogram
命令作为目标时,有时可能会看到意外结果。 某些事件可能不会出现在预期的槽中,而其他槽则可能显示比预期的事件计数更高的计数。
如果将事件分配到槽时发生哈希冲突,则可能会发生这种情况。 虽然这种情况很少见,如果发生哈希冲突,则本应在一个槽中计数的事件会计入到另一个槽中。 出于此原因,应注意假设事件未发生,只是因为特定槽中的计数显示为零。
例如,请考虑以下情形:
- 设置扩展事件会话,使用
histogram
作为目标并按object_id
进行分组,以便收集存储过程执行。 - 执行存储过程 A。然后再执行存储过程 B。
如果两个存储过程的 object_id
所返回哈希函数的值相同,直方图显示存储过程 A 被执行两次,并且存储过程 B 不会显示。
若要解决非重复值数量相对较少这一问题,请将直方图槽的数量设置得高于预期非重复值的平方。 例如,如果 histogram
目标的 source
设置为 table_name
事件字段,且数据库中有 20 个表,则 20*20 = 400。 2 比 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
);
捕获到以下数据。 value
列中的值是 system_thread_id
值。 例如,236 的总锁数在 线程 6540 下取得。
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_id
是可为 histogram
目标提供值的 checkpoint_begin
事件上的唯一字段。
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,我们看到下列行集中有大约 16 个 lock_acquired
事件的字段。 此处显示的行集已手动拆分以显示我们的示例可匹配哪些字段。 对某些字段(如 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_columns
和 end_matching_columns
的以逗号分隔的字段序列必须相同。 即使空格正确,但是以逗号分隔的值中所涉及的字段之间不允许有制表符或换行符。
若要缩小结果范围,我们首先从 sys.objects
中进行选择来查找测试表的 object_id
。 我们在 ADD EVENT ... (WHERE ...)
子句为那个对象 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
);
若要测试事件会话,我们故意阻止已获取的两把锁被释放。 通过以下 T-SQL 步骤达到此目的:
BEGIN TRANSACTION
。UPDATE MyTable...
。- 在检查目标之前,有意不提出问题
COMMIT TRANSACTION
。 - 测试后,我们提出了
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 或更小的值。 使用更大的值可能会占用更多不必要的内存。
默认情况下,SQL Server 不限制 ring_buffer
目标的 MAX_MEMORY
,而在 Azure SQL 数据库和 Azure SQL 托管实例中则限制为 32MB。
如以下示例所示,通过将其转化为 XML 来使用 ring_buffer
中的数据。 转换过程中会省略任何 4MB XML 文档无法容纳下的数据。 因此,即使是使用更大的 MAX_MEMORY
值捕获环形缓冲区中的更多事件(或将此参数保留为其默认值不变),也无法使用全部数据,因为考虑到 XML 标记和 Unicode 字符串的开销问题,XML 文档大小的上限为 4MB。
例如,如果 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
。 从系统视图 sys.dm_xe_session_targets
检索的 XML 数据 。
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;
用 XQuery 将 XML 作为行集查看
若要将前述的 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)
<event>
元素上的 timestamp= attribute's value。- “
'(...)[1]'
”构造可确保每次迭代只返回 1 个值,这是 XML 数据类型变量和列的.value()
XQuery 方法的必需限制。
(B)
- 其 name= attribute 等于“
mode
”的<data>
元素内的<text>
元素的内部值。
(C)
- 其 name= attribute 等于“
transaction_id
”的<data>
元素内的<value>
元素的内部值。
(D)
<event>
包含<action>
。<action>
的 name= attribute 等于database_name
,且 package= attribute 等于sqlserver
(而不是package0
),则获取<value>
元素的内部值。
(E)
CROSS APPLY
导致其name
属性等于lock_acquired
的每个单个<event>
元素都进行重复处理。- 这适用于由前述
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 目标
可以在用 C# 等语言编写的 .NET 程序中使用 event_stream
目标。 C# 和其他.NET 开发人员可以通过 Microsoft.SqlServer.XEvents.Linq
命名空间里的 .NET Framework 类访问事件流。 此目标不能在 T-SQL 中使用。
如果遇到错误 25726,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
目标进行取决时,意味着事件流填满数据的速度快于客户端使用数据的速度。 这导致数据库引擎断开与事件流的连接以避免影响数据库引擎的性能。