1

我目前正在开展一个项目,以使用扩展事件分析我们的一个多维数据集上维度/度量的使用情况。由于我们在 SQL Server 2012 上,扩展事件 GUI 不可用。我正在使用 sys.fn_xe_file_target_read_file 以 XML 格式返回文件,每行一个事件。

然后,我将 XML 中的关键元素解析为临时表。

select xe.TraceFileName
     , xe.TraceEvent
     , xe.EventDataXML.value('(/event/data[@name="EventSubclass"]/value)[1]', 'int')               as EventSubclass
     , xe.EventDataXML.value('(/event/data[@name="ServerName"]/value)[1]', 'varchar(50)')          as ServerName
     , xe.EventDataXML.value('(/event/data[@name="DatabaseName"]/value)[1]', 'varchar(50)')        as DatabaseName
     , xe.EventDataXML.value('(/event/data[@name="NTDomainName"]/value)[1]', 'varchar(50)')        as NTDomainName
     , xe.EventDataXML.value('(/event/data[@name="NTUserName"]/value)[1]', 'varchar(50)')          as NTUserName
     , xe.EventDataXML.value('(/event/data[@name="NTCanonicalUserName"]/value)[1]', 'varchar(50)') as NTCanonicalUserName
     , xe.EventDataXML.value('(/event/data[@name="ConnectionID"]/value)[1]', 'int')                as ConnectionID
     , xe.EventDataXML.value('(/event/data[@name="StartTime"]/value)[1]', 'datetime')              as StartTime
     , xe.EventDataXML.value('(/event/data[@name="EndTime"]/value)[1]', 'datetime')                as EndTime
     , xe.EventDataXML.value('(/event/data[@name="Duration"]/value)[1]', 'bigint')                 as Duration
     , xe.EventDataXML.value('(/event/data[@name="TextData"]/value)[1]', 'varchar(max)')           as TextData
into #List
from
(
    select [file_name]              as TraceFileName
         , object_name              as TraceEvent
         , convert(xml, event_data) as EventDataXML
    from sys.fn_xe_file_target_read_file('path\filename*.xel', null, null, null)
) xe;

.xel 文件附加到每一天。我需要设置一个机制(使用 SSIS)包来每天存档文件并应用上面的 sql 逻辑将数据读入临时/临时表/

但是,我正在努力在 SSIS 上找到合适的连接器。他们都不允许我从其文件夹中获取 .xel 文件。

4

1 回答 1

3

TSQL 正在处理文件的读取,sys.fn_xe_file_target_read_file所以我认为您正在查看数据流任务。源将有一个以上述查询为起点的 OLE DB Source 组件。

这会将这 N 列添加到数据流中,然后您可以随意放置它们。如果它们都在同一台服务器上,我会跳过数据流并改用执行 SQL 任务。

这是我XE监控的一部分,也许对你有用

CREATE PROCEDURE dbo.ExtendedEventCaptureStop
AS
BEGIN

    SET NOCOUNT ON;

    --------------------------------------------------------------------------------
    -- Turn off our extended event
    --------------------------------------------------------------------------------
    IF EXISTS
    (
        -- When a XE is active, then there is an entry
        -- in sys.dm_xe_sessions
        SELECT
            *
        FROM
            sys.dm_xe_sessions AS DXS
            INNER JOIN 
                sys.server_event_sessions AS SES
                ON SES.name = DXS.name
        WHERE
            SES.name = N'what_queries_are_failing'
    )
    BEGIN
        -- Start the session
        ALTER EVENT SESSION what_queries_are_failing
        ON SERVER STATE = STOP;
    END

    --------------------------------------------------------------------------------
    -- Extract data from our XE
    --------------------------------------------------------------------------------
    ;
    WITH events_cte AS
    (
        SELECT
            DATEADD(mi,
            DATEDIFF(mi, GETUTCDATE(), CURRENT_TIMESTAMP),
            xevents.event_data.value('(event/@timestamp)[1]', 'datetime2')) AS [err_timestamp],
            xevents.event_data.value('(event/data[@name="severity"]/value)[1]', 'bigint') AS [err_severity],
            xevents.event_data.value('(event/data[@name="error_number"]/value)[1]', 'bigint') AS [err_number],
            xevents.event_data.value('(event/data[@name="message"]/value)[1]', 'nvarchar(512)') AS [err_message],
            xevents.event_data.value('(event/action[@name="database_id"]/value)[1]', 'int') AS [database_id],
            xevents.event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS [sql_text],
            xevents.event_data,
            xevents.event_data.value('(event/action[@name="username"]/value)[1]', 'nvarchar(512)') AS [username],
            'what_queries_are_failing' AS session_name
        FROM sys.fn_xe_file_target_read_file
        (
            'D:\mssql\MSSQL13.MSSQLSERVER\mssql\extendedevents\what_queries_are_failing*.xel'
        ,   'D:\mssql\MSSQL13.MSSQLSERVER\mssql\extendedevents\what_queries_are_failing*.xem'
        ,   NULL
        ,   NULL) AS fxe
        CROSS APPLY (SELECT CAST(event_data as XML) AS event_data) AS xevents
    )
    INSERT INTO
        dbo.ExtendedEventErrorCapture
    (
        err_timestamp
    ,   err_severity
    ,   err_number
    ,   err_message
    ,   database_id
    ,   sql_text
    ,   event_data
    ,   session_name
    ,   username
    )
    SELECT
        E.err_timestamp
    ,   E.err_severity
    ,   E.err_number
    ,   E.err_message
    ,   E.database_id
    ,   E.sql_text
    ,   E.event_data
    ,   E.session_name
    ,   E.username
    FROM
        events_cte AS E;

    --------------------------------------------------------------------------------
    -- Get rid our extended event files only if the XE is turned off
    -- or no longer exists
    --------------------------------------------------------------------------------
    IF NOT EXISTS
    (
        SELECT
            1
        FROM
            sys.dm_xe_sessions AS DXS
            INNER JOIN 
                sys.server_event_sessions AS SES
                ON SES.name = DXS.name
        WHERE
            SES.name = N'what_queries_are_failing'

        UNION ALL
        SELECT
            1
        FROM
            sys.server_event_sessions AS SES
        WHERE
            SES.name = N'what_queries_are_failing'

    )
    BEGIN
        -- Assumes you've turned on xp_cmdshell
        EXECUTE sys.xp_cmdshell'del D:\mssql\MSSQL13.MSSQLSERVER\mssql\extendedevents\what_queries_are_failing*.xe*';
    END

END
GO

更改文件位置和会话名称,它会停止 XE,因此我们不必担心文件被锁定。我将 XE 中的数据解析到我的表中,然后删除文件夹中剩余的所有 XE 文件。

哦,但是现在我的 XE 会话已停止,我应该重新启动它。就是这个程序

CREATE PROCEDURE dbo.ExtendedEventCaptureStart
AS
BEGIN

    SET NOCOUNT ON;
    --------------------------------------------------------------------------------
    -- Create the table to store out the XE data
    --------------------------------------------------------------------------------
    IF NOT EXISTS
    (
        SELECT
            *
        FROM
            sys.schemas AS S
            INNER JOIN 
                sys.tables AS T
            ON T.schema_id = S.schema_id
        WHERE
            T.name = 'ExtendedEventErrorCapture'
            AND S.name = 'dbo'
    )
    BEGIN
        CREATE TABLE 
            dbo.ExtendedEventErrorCapture
        (
            err_timestamp datetime2(7) NULL
        ,   err_severity bigint NULL
        ,   err_number bigint NULL
        ,   err_message nvarchar(512) NULL
        ,   database_id int NULL
        ,   sql_text nvarchar(MAX) NULL
        ,   event_data xml NULL
        ,   session_name sysname
        ,   username nvarchar(512)
        )
        -- This is only vaild for a Develper/Enterprise edition license
        WITH (DATA_COMPRESSION = PAGE);
    END

    --------------------------------------------------------------------------------
    -- Create the extended event to keep track of bad sql queries
    --------------------------------------------------------------------------------
    IF NOT EXISTS
    (
        SELECT
            *
        FROM
            sys.server_event_sessions AS SES
        WHERE
            SES.name = N'what_queries_are_failing'
    )
    BEGIN
        --Create an extended event session
        CREATE EVENT SESSION
            what_queries_are_failing
        ON SERVER
        ADD EVENT sqlserver.error_reported
        (
            ACTION (sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.database_id, sqlserver.username)
            WHERE ([severity]> 10)
        )
        ADD TARGET package0.asynchronous_file_target
        (set filename = 'D:\mssql\MSSQL13.MSSQLSERVER\mssql\extendedevents\what_queries_are_failing.xel' ,
            metadatafile = 'D:\mssql\MSSQL13.MSSQLSERVER\mssql\extendedevents\what_queries_are_failing.xem',
            max_file_size = 512,
            increment = 16,
            max_rollover_files = 5)
        WITH (MAX_DISPATCH_LATENCY = 5SECONDS);

    END

    --------------------------------------------------------------------------------
    -- Turn on the extended event
    --------------------------------------------------------------------------------
    IF NOT EXISTS
    (
        -- When a XE is active, then there is an entry
        -- in sys.dm_xe_sessions
        SELECT
            *
        FROM
            sys.dm_xe_sessions AS DXS
            INNER JOIN 
                sys.server_event_sessions AS SES
                ON SES.name = DXS.name
        WHERE
            SES.name = N'what_queries_are_failing'
    )
    BEGIN
        -- Start the session
        ALTER EVENT SESSION what_queries_are_failing
        ON SERVER STATE = START;
    END
END

所以现在我的 SSIS 包将是一个执行 SQL 任务,里面有两个语句

EXECUTE dbo.ExtendedEventCaptureStop;
EXECUTE dbo.ExtendedEventCaptureStart;
于 2019-12-10T16:30:39.030 回答