【问题标题】:Extended Event force order of sys.fn_xe_file_target_read_file() DMF resultssys.fn_xe_file_target_read_file() DMF 结果的扩展事件强制顺序
【发布时间】:2025-11-23 11:15:01
【问题描述】:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) 2012 年 6 月 28 日 08:36:30 版权所有 (c) Microsoft Corporation Enterprise Edition (64 位)在 Windows NT 6.1(内部版本 7601:Service Pack 1)上

在使用 sys.fn_xe_file_target_read_file() DMF 读取扩展事件 .xel 日志文件时,有没有办法保证结果的顺序?理想情况下,我想根据它们插入 .xel 文件的顺序对记录 1..X 进行编号。

我需要多次轮询文件目标并将新记录插入表中。如果我可以保证结果的顺序,那么我可以添加元数据列“条目号”,并使用此列来避免在多次执行中插入相同的记录,即

SELECT  entries.EntryNumber
        ,entries.file_name
        ,entries.data
        ,entries.file_offset
FROM    (
        SELECT  ROW_NUMBER() OVER (ORDER BY <GUARANTEE ORDERING BASED ON ORDER OF INSERTION>) AS EntryNumber,
                file_name,
                CONVERT (XML, event_data) AS data
                ,file_offset
        FROM    sys.fn_xe_file_target_read_file ('C:\ExEvent_0_123456789.xel', 'C:\ExEvent_0_123456789.xem', NULL, NULL)
                ) entries
WHERE   NOT EXISTS 
        (
        SELECT  1
        FROM    dbo.ExEventLog d
        WHERE   entries.EntryNumber = d.EntryNumber                         
        )

如果无法做到这一点,我能否保证将所有具有相同“file_offset”值的记录一次性加载到 .xel 文件中?例如,如果我在 .xel 文件中查询 'file_offset' 为 123 的所有记录,我能否保证随后不会加载具有 'file_offset' 为 123 的其他记录?

这是基于创建扩展事件 WITH MAX_DISPATCH_LATENCY = 1 SECONDS 并每 60 秒轮询 .xel 文件。

由于这个错误/功能,我不习惯使用 @initial_file_name 和 @initial_offset 参数:http://connect.microsoft.com/SQLServer/feedback/details/714286/sys-fn-file-target-read-file-reads-incorrect-files-when-offset-reading#details

【问题讨论】:

    标签: sql sql-server-2008 sql-server-2008-r2 monitoring extended-events


    【解决方案1】:

    您可以使用event_data 中根节点的timestamp 属性。

    SELECT  entries.EntryNumber
            ,entries.file_name
            ,entries.data
            ,entries.file_offset
    FROM    (
            SELECT  ROW_NUMBER() OVER (ORDER BY X.data.value('(/event/@timestamp)[1]', 'datetime')) AS EntryNumber
                    ,file_name
                    ,X.data
                    ,file_offset
            FROM    sys.fn_xe_file_target_read_file ('C:\ExEvent_0_123456789.xel', 'C:\ExEvent_0_123456789.xem', NULL, NULL)
              CROSS APPLY (SELECT CONVERT(XML, event_data) AS data) AS X
            ) entries
    

    【讨论】:

      【解决方案2】:

      如果您想保证基于 ORDER OF INSERTION 的排序,请使用带有 identity(int, 1, 1) 列的临时表:

      SELECT  
              file_name
              ,CONVERT (XML, event_data) AS data
              ,file_offset
              ,identity(int, 1, 1) AS EntryNumber
      into #tmp
      FROM    sys.fn_xe_file_target_read_file ('C:\ExEvent_0_123456789.xel', 'C:\ExEvent_0_123456789.xem', NULL, NULL)
      
      SELECT  entries.EntryNumber
          ,entries.file_name
          ,entries.data
          ,entries.file_offset
      FROM #tpm entries
      WHERE   NOT EXISTS 
          (
          SELECT  1
          FROM    dbo.ExEventLog d
          WHERE   entries.EntryNumber = d.EntryNumber                         
          )
      
      DROP TABLE #tmp
      

      Row_Number 并不意味着这样做。

      【讨论】: