利用 trace 监控慢查询
- 第1步,创建存储过程 master..dba_trace_slowquery 用于定义 trace 监控指标
注:3 天后停止监控、每个日志文件最大1GB、最多5个(循环覆盖,最多占用5G空间),慢查询定义:耗时>=3秒 或 Reads >= 40000 或 CPU > 1000
USE master
GO
IF OBJECT_ID('dba_trace_slowquery') IS NOT NULL
DROP PROCEDURE dba_trace_slowquery
GO
CREATE PROC dba_trace_slowquery
@tracepath NVARCHAR(200)
AS
/***************************************************************************************
Funtion : 跟踪RPC:Completed、SQL:BatchCompleted
Input :@tracepath 输入 设置跟踪文件的存放目录.
Author : dba_yuxiukai 2015/12/15 新增 编写草稿.
Sample : exec master..dba_trace_slowquery @tracepath='d:\sqldata\trace'
***************************************************************************************/
BEGIN
DECLARE @oldtrace INT
DECLARE @mdir NVARCHAR(200)
DECLARE @rc INT
DECLARE @traceid INT
DECLARE @options INT
DECLARE @maxfilesize BIGINT
DECLARE @endtime DATETIME
DECLARE @filecount INT
DECLARE @tracefile NVARCHAR(200)
DECLARE @BigIntFilter BIGINT
DECLARE @on BIT
SET @on = 1
SET @options = 2
SET @filecount = 5 --.最多5个日志文件
SET @maxfilesize = 1024 --.单个文件最大1GB
SET @endtime = GETDATE() + 3 --.默认3天后停止监控
--Create the folder.
SET @mdir = N'EXECUTE master.dbo.xp_create_subdir ''' + @tracepath + ''''
EXEC sp_executesql @mdir
--Stop old trace.
SELECT @oldtrace = id FROM sys.traces WHERE path LIKE @tracepath +'\dba_trace_slowquery%' AND status = 1
IF @oldtrace IS NOT NULL
BEGIN
EXEC sp_trace_setstatus @oldtrace, 0
EXEC sp_trace_setstatus @oldtrace, 2
END
--Create new trace.
SET @tracefile = @tracepath+'\dba_trace_slowquery' + CONVERT(VARCHAR(8),GETDATE(),112) + LEFT(NEWID(),4)
EXEC @rc = sp_trace_Create @traceid OUTPUT,@options,@tracefile,@maxfilesize,@endtime,@filecount
IF (@rc != 0) GOTO error
--Set the events
EXEC sp_trace_setevent @traceid, 10, 1, @on --event_number(RPC:Completed)
EXEC sp_trace_setevent @traceid, 10, 3, @on
EXEC sp_trace_setevent @traceid, 10, 8, @on
EXEC sp_trace_setevent @traceid, 10, 10, @on
EXEC sp_trace_setevent @traceid, 10, 11, @on
EXEC sp_trace_setevent @traceid, 10, 12, @on
EXEC sp_trace_setevent @traceid, 10, 13, @on
EXEC sp_trace_setevent @traceid, 10, 14, @on
EXEC sp_trace_setevent @traceid, 10, 15, @on
EXEC sp_trace_setevent @traceid, 10, 16, @on
EXEC sp_trace_setevent @traceid, 10, 17, @on
EXEC sp_trace_setevent @traceid, 10, 18, @on
EXEC sp_trace_setevent @traceid, 10, 26, @on
EXEC sp_trace_setevent @traceid, 10, 31, @on
EXEC sp_trace_setevent @traceid, 10, 34, @on
EXEC sp_trace_setevent @traceid, 10, 35, @on
EXEC sp_trace_setevent @traceid, 10, 41, @on
EXEC sp_trace_setevent @traceid, 12, 1, @on --event_number(SQL:BatchCompleted)
EXEC sp_trace_setevent @traceid, 12, 3, @on
EXEC sp_trace_setevent @traceid, 12, 8, @on
EXEC sp_trace_setevent @traceid, 12, 10, @on
EXEC sp_trace_setevent @traceid, 12, 11, @on
EXEC sp_trace_setevent @traceid, 12, 12, @on
EXEC sp_trace_setevent @traceid, 12, 13, @on
EXEC sp_trace_setevent @traceid, 12, 14, @on
EXEC sp_trace_setevent @traceid, 12, 15, @on
EXEC sp_trace_setevent @traceid, 12, 16, @on
EXEC sp_trace_setevent @traceid, 12, 17, @on
EXEC sp_trace_setevent @traceid, 12, 18, @on
EXEC sp_trace_setevent @traceid, 12, 26, @on
EXEC sp_trace_setevent @traceid, 12, 31, @on
EXEC sp_trace_setevent @traceid, 12, 34, @on
EXEC sp_trace_setevent @traceid, 12, 35, @on
EXEC sp_trace_setevent @traceid, 12, 41, @on
EXEC sp_trace_setevent @traceid, 92, 1, @on --event_number(Data File Auto Grow)
EXEC sp_trace_setevent @traceid, 92, 3, @on
EXEC sp_trace_setevent @traceid, 92, 4, @on
EXEC sp_trace_setevent @traceid, 92, 11, @on
EXEC sp_trace_setevent @traceid, 92, 12, @on
EXEC sp_trace_setevent @traceid, 92, 13, @on
EXEC sp_trace_setevent @traceid, 92, 14, @on
EXEC sp_trace_setevent @traceid, 92, 15, @on
EXEC sp_trace_setevent @traceid, 92, 22, @on
EXEC sp_trace_setevent @traceid, 92, 24, @on
EXEC sp_trace_setevent @traceid, 92, 25, @on
EXEC sp_trace_setevent @traceid, 92, 26, @on
EXEC sp_trace_setevent @traceid, 92, 32, @on
EXEC sp_trace_setevent @traceid, 92, 35, @on
EXEC sp_trace_setevent @traceid, 92, 36, @on
EXEC sp_trace_setevent @traceid, 92, 41, @on
EXEC sp_trace_setevent @traceid, 93, 1, @on --event_number(Log File Auto Grow)
EXEC sp_trace_setevent @traceid, 93, 3, @on
EXEC sp_trace_setevent @traceid, 93, 4, @on
EXEC sp_trace_setevent @traceid, 93, 11, @on
EXEC sp_trace_setevent @traceid, 93, 12, @on
EXEC sp_trace_setevent @traceid, 93, 13, @on
EXEC sp_trace_setevent @traceid, 93, 14, @on
EXEC sp_trace_setevent @traceid, 93, 15, @on
EXEC sp_trace_setevent @traceid, 93, 22, @on
EXEC sp_trace_setevent @traceid, 93, 24, @on
EXEC sp_trace_setevent @traceid, 93, 25, @on
EXEC sp_trace_setevent @traceid, 93, 26, @on
EXEC sp_trace_setevent @traceid, 93, 32, @on
EXEC sp_trace_setevent @traceid, 93, 35, @on
EXEC sp_trace_setevent @traceid, 93, 36, @on
EXEC sp_trace_setevent @traceid, 93, 41, @on
EXEC sp_trace_setevent @traceid, 94, 1, @on --event_number(Data File Auto Shrink)
EXEC sp_trace_setevent @traceid, 94, 3, @on
EXEC sp_trace_setevent @traceid, 94, 4, @on
EXEC sp_trace_setevent @traceid, 94, 11, @on
EXEC sp_trace_setevent @traceid, 94, 12, @on
EXEC sp_trace_setevent @traceid, 94, 13, @on
EXEC sp_trace_setevent @traceid, 94, 14, @on
EXEC sp_trace_setevent @traceid, 94, 15, @on
EXEC sp_trace_setevent @traceid, 94, 22, @on
EXEC sp_trace_setevent @traceid, 94, 24, @on
EXEC sp_trace_setevent @traceid, 94, 25, @on
EXEC sp_trace_setevent @traceid, 94, 26, @on
EXEC sp_trace_setevent @traceid, 94, 32, @on
EXEC sp_trace_setevent @traceid, 94, 35, @on
EXEC sp_trace_setevent @traceid, 94, 36, @on
EXEC sp_trace_setevent @traceid, 94, 41, @on
EXEC sp_trace_setevent @traceid, 95, 1, @on --event_number(Log File Auto Shrink)
EXEC sp_trace_setevent @traceid, 95, 3, @on
EXEC sp_trace_setevent @traceid, 95, 4, @on
EXEC sp_trace_setevent @traceid, 95, 11, @on
EXEC sp_trace_setevent @traceid, 95, 12, @on
EXEC sp_trace_setevent @traceid, 95, 13, @on
EXEC sp_trace_setevent @traceid, 95, 14, @on
EXEC sp_trace_setevent @traceid, 95, 15, @on
EXEC sp_trace_setevent @traceid, 95, 22, @on
EXEC sp_trace_setevent @traceid, 95, 24, @on
EXEC sp_trace_setevent @traceid, 95, 25, @on
EXEC sp_trace_setevent @traceid, 95, 26, @on
EXEC sp_trace_setevent @traceid, 95, 32, @on
EXEC sp_trace_setevent @traceid, 95, 35, @on
EXEC sp_trace_setevent @traceid, 95, 36, @on
EXEC sp_trace_setevent @traceid, 95, 41, @on
--Set the Filters
EXEC sp_trace_setfilter @traceid, 1, 0, 1, NULL
EXEC sp_trace_setfilter @traceid = @traceid, @columnid = 10, @logical_operator = 0, @comparison_operator = 7, @value = N'SQL Profiler%' --AND ApplicationName NOT LIKE N'SQL Profiler%'
SET @BigIntFilter = 3000000
EXEC sp_trace_setfilter @traceid = @traceid, @columnid = 13, @logical_operator = 0, @comparison_operator = 4, @value = @BigIntFilter --AND Duration >= 3000000
SET @BigIntFilter = 40000
EXEC sp_trace_setfilter @traceid = @traceid, @columnid = 16, @logical_operator = 1, @comparison_operator = 4, @value = @BigIntFilter --OR Reads >= 40000
EXEC sp_trace_setfilter @traceid = @traceid, @columnid = 18, @logical_operator = 1, @comparison_operator = 2, @value = 1000 --OR CPU > 1000
--Set the trace status to start
EXEC sp_trace_setstatus @traceid, 1
--display trace id for future references
SELECT traceid = @traceid
GOTO finish
error:
SELECT ErrorCode = @rc
finish:
END
GO
- 第2步,开启 trace 监控,可自定义日志路径,示例 d:\trace
注:若运行期间 SQLServer 服务重启,则需重手动再次开启
exec master..dba_trace_slowquery @tracepath='d:\trace'
- 第3步,开启监控后,根据返回的 trace id 查看具体的慢查询记录
注:开启 Trace 服务之后通常有一个 trace 为 1 的默认监控,以下示例查询的监控是 id = 2
--获取默认跟踪文件中前n行执行内容
DECLARE @TracePath VARCHAR(200)
SELECT @TracePath = path FROM sys.traces WHERE id = 2
-- SELECT * FROM sys.traces
SELECT TOP 100
gt.[HostName]
,gt.[DatabaseName]
,gt.[SPID]
,gt.[ObjectName]
,gt.[objecttype] [ObjectTypeID]
,gt.[Duration]/1000 [Duration_ms]
,gt.[StartTime]
,gt.[Reads] [Reads]
,gt.[Writes] [Writes]
,gt.[CPU] [CPU]
,e.[category_id] [CategoryID]
,c.[Name] [Category]
,gt.[EventClass] [EventID]
,e.[Name] [EventName]
,gt.[LoginName]
,gt.[ApplicationName]
,case gt.Error when 0 then 'OK' when 1 then 'Error' when 2 then 'Abort' END AS Error
,gt.[TextData]
FROM fn_trace_gettable(@TracePath, DEFAULT) gt
LEFT JOIN sys.trace_subclass_values sv ON gt.[eventclass] = sv.[trace_event_id] AND sv.[subclass_value] = gt.[objecttype]
INNER JOIN sys.trace_events e ON gt.[eventclass] = e.[trace_event_id]
INNER JOIN sys.trace_categories c ON e.[category_id] = c.[category_id]
WHERE gt.[spid] > 50 --50以内的spid为系统使用
--AND gt.loginname <> 'dba_admin'
--AND gt.[StartTime] > DATEADD(MINUTE,-30,GETDATE())
--AND gt.[DatabaseName] = 'master' --根据DatabaseName过滤
ORDER BY gt.[Duration] DESC
- 第4步,若要提前停止监控,可根据 trace id 来进行关闭,示例 id = 2
--.执行如下语句找出trace监控的id
select id,* from sys.traces
--.根据id停止跟踪,示例停止id为2的监控
declare @id int = 2
exec sp_trace_setstatus @id,0
exec sp_trace_setstatus @id,2