You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server扩展事件:关联跟踪失败RPC调用与抛出的异常

关联RPC事件与错误事件以追踪失败的存储过程调用

我之前处理过完全相同的场景——要追踪失败的RPC调用,同时获取存储过程语句、参数和抛出的异常,但卡在了关联不同事件的环节。下面是我验证过的可行方案,核心是利用SQL Server扩展事件中的会话/请求唯一标识来把RPC执行事件和错误事件绑定到同一执行上下文:

1. 创建包含关联字段的扩展事件会话

所有rpc_starting、rpc_completed和error_reported事件都会携带session_id和request_id字段,这两个字段的组合可以唯一标识一个数据库请求。我们可以创建一个扩展事件会话,同时捕获这三类事件,并添加必要的动作来获取所需信息:

CREATE EVENT SESSION [TrackFailedRPC] ON SERVER 
ADD EVENT sqlserver.rpc_starting(
    ACTION(
        sqlserver.sql_text, 
        sqlserver.session_id, 
        sqlserver.request_id, 
        sqlserver.username,
        sqlserver.rpc_parameters -- 捕获RPC调用的输入/输出参数
    )
    WHERE ([sqlserver].[is_system]=(0)) -- 排除系统进程
),
ADD EVENT sqlserver.rpc_completed(
    ACTION(
        sqlserver.sql_text, 
        sqlserver.session_id, 
        sqlserver.request_id, 
        sqlserver.username,
        sqlserver.rpc_parameters
    )
    WHERE ([sqlserver].[is_system]=(0))
),
ADD EVENT sqlserver.error_reported(
    ACTION(
        sqlserver.sql_text, 
        sqlserver.session_id, 
        sqlserver.request_id, 
        sqlserver.username
    )
    WHERE (
        [sqlserver].[is_system]=(0) 
        AND [severity]>=11 -- 只捕获严重程度≥11的错误,可按需调整
    )
)
ADD TARGET package0.event_file(
    SET filename=N'TrackFailedRPC.xel', 
    max_file_size=(5), -- 单个文件最大5GB
    max_rollover_files=(4) -- 最多保留4个滚动文件
)
WITH (STARTUP_STATE=OFF);

2. 启动会话并捕获数据

创建完成后,启动会话开始捕获数据:

ALTER EVENT SESSION [TrackFailedRPC] ON SERVER STATE = START;

当有失败的RPC调用发生时,相关的事件会被写入指定的.xel文件中。

3. 关联事件并提取所需信息

通过查询扩展事件文件,我们可以用session_id和request_id关联同一请求的RPC事件和错误事件,提取完整的调用语句、参数和异常信息:

WITH EventData AS (
    SELECT
        CAST(event_data AS XML) AS event_data,
        file_name,
        file_offset
    FROM sys.fn_xe_file_target_read_file('TrackFailedRPC*.xel', NULL, NULL, NULL)
),
ParsedEvents AS (
    SELECT
        event_data.value('(event/@name)[1]', 'NVARCHAR(100)') AS EventName,
        event_data.value('(event/action[@name="session_id"]/value)[1]', 'INT') AS SessionID,
        event_data.value('(event/action[@name="request_id"]/value)[1]', 'INT') AS RequestID,
        event_data.value('(event/action[@name="sql_text"]/value)[1]', 'NVARCHAR(MAX)') AS FullRPCStatement,
        event_data.value('(event/action[@name="rpc_parameters"]/value)[1]', 'NVARCHAR(MAX)') AS RPCParameters,
        event_data.value('(event/data[@name="error_number"]/value)[1]', 'INT') AS ErrorNumber,
        event_data.value('(event/data[@name="message"]/value)[1]', 'NVARCHAR(MAX)') AS ErrorMessage,
        event_data.value('(event/@timestamp)[1]', 'DATETIME2') AS EventTimestamp
    FROM EventData
)
SELECT
    pe_rpc.EventTimestamp AS RPCTimestamp,
    pe_rpc.FullRPCStatement,
    pe_rpc.RPCParameters,
    pe_error.EventTimestamp AS ErrorTimestamp,
    pe_error.ErrorNumber,
    pe_error.ErrorMessage
FROM ParsedEvents pe_rpc
JOIN ParsedEvents pe_error 
    ON pe_rpc.SessionID = pe_error.SessionID 
    AND pe_rpc.RequestID = pe_error.RequestID
WHERE pe_rpc.EventName IN ('rpc_starting', 'rpc_completed')
  AND pe_error.EventName = 'error_reported'
ORDER BY pe_rpc.EventTimestamp DESC;

4. 关键注意事项

  • 过滤条件优化:如果你的环境并发量高,建议在扩展事件会话中添加更具体的过滤条件(比如指定目标数据库、存储过程名称或用户),避免生成过大的事件文件。
  • 错误匹配:同一个请求可能会触发多个error_reported事件,建议通过EventTimestamp的先后顺序来匹配对应RPC调用的错误。
  • 实时监控:如果需要实时追踪,可以将目标改为package0.ring_buffer,或者集成到SQL Server Management Studio的扩展事件查看器中。

内容的提问来源于stack exchange,提问作者Juozas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:30:04