[实战]分钟级简易数据库执行日志

相信很多童鞋都知道数据库忽然性能下来的时候,在没有其他辅助工具的情况下,会登上去跑个sp_who2来看看就行什么东西block住了,那么其实就可以用这个东西来做文章了。直接贴段代码吧,核心的出自Kent之手,我只是把他变成个SP,并起了个SQL Schedule Job设置成每分钟跑一次,跑挂了不要紧,下一分钟再跑就行,我们要的只是简易日志。这样就不用说抢着时间点去跑sp_who2了。出来的效果大概是这样,最后一列eventinfo就是在跑什么,就连schedule job的step id都能出来。enjoy :) 

 

 

CREATE PROC [dbo].[usp_log_sp_who2] 
AS
BEGIN

DECLARE @tempTable TABLE (SPID INT,Status VARCHAR(255),
      [Login]  VARCHAR(255),HostName  VARCHAR(255),
      BlkBy  VARCHAR(255),DBName  VARCHAR(255),
      Command VARCHAR(255),CPUTime INT,
      DiskIO INT,LastBatch VARCHAR(255),
      ProgramName VARCHAR(255),SPID2 INT,
      REQUESTID INT, 
      [parameters] SMALLINT, eventinfo NVARCHAR(MAX));

INSERT INTO @tempTable (spid, [status], [login], hostname, blkby, dbname, command, cputime, diskio, lastbatch, programname, spid2, requestid) EXEC sp_who2
DECLARE @t1 TABLE (eventtype nvarchar(MAX), [parameters] SMALLINT, eventinfo NVARCHAR(MAX))
DECLARE @sql NVARCHAR(MAX) 
DECLARE @spid INT, @parameters smallint, @eventinfo NVARCHAR(MAX)
DECLARE curTempTable CURSOR FOR SELECT spid FROM @tempTable FOR UPDATE OF [parameters], [eventinfo]

OPEN curTempTable
FETCH curTempTable INTO @spid
WHILE @@FETCH_STATUS = 0
BEGIN
   DELETE FROM @t1
   SET @sql = N'dbcc inputbuffer(' + CONVERT(NVARCHAR(MAX), @spid) + N')'
   INSERT @t1 EXEC(@sql)
   SELECT TOP 1 @parameters = [parameters], @eventinfo = [eventinfo] FROM @t1
   UPDATE @tempTable SET [parameters] = @parameters, [eventinfo] = @eventinfo WHERE CURRENT OF curTempTable
   FETCH NEXT FROM curTempTable INTO @spid
END
CLOSE curTempTable

DECLARE @now DATETIME = GETDATE()
DELETE LOG_SP_WHO2 WHERE [Branch]<DATEADD(day, -7, @now)
--这里-7其实随你喜欢,我只是需要一周内的日志而已,所以就把一周前的删除了
INSERT INTO LOG_SP_WHO2 SELECT @now, * FROM @tempTable END

 

--基础表
CREATE TABLE [dbo].[LOG_SP_WHO2](
    [Branch] [datetime] NULL,
    [SPID] [int] NULL,
    [Status] [varchar](255) NULL,
    [Login] [varchar](255) NULL,
    [HostName] [varchar](255) NULL,
    [BlkBy] [varchar](255) NULL,
    [DBName] [varchar](255) NULL,
    [Command] [varchar](255) NULL,
    [CPUTime] [int] NULL,
    [DiskIO] [int] NULL,
    [LastBatch] [varchar](255) NULL,
    [ProgramName] [varchar](255) NULL,
    [SPID2] [int] NULL,
    [REQUESTID] [int] NULL,
    [parameters] [smallint] NULL,
    [eventinfo] [nvarchar](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

--索引的随君所愿,我这里只是建了个按时间的聚集索引(非唯一) CREATE CLUSTERED INDEX [IX_LOG_SP_WHO2] ON [dbo].[LOG_SP_WHO2] ( [Branch] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO

 

posted @ 2018-12-27 19:30  黄铨  阅读(519)  评论(1编辑  收藏  举报