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


    相信很多童鞋都知道数据库忽然性能下来的时候,在没有其他辅助工具的情况下,会登上去跑个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
  • 相关阅读:
    命令模式
    软件设计师_例题
    软件设计师_计算机系统基础(1.1)
    ForkJoin之ForkJoinTask框架学习笔记
    Oracle使用语句块之循环插入数据
    SpringCloud搭建分布式配置中心(基于git)
    Docker配置JDK1.8
    Linux命令查看文件内容
    Mac配置maven环境命令
    Docker安装mysql8
  • 原文地址:https://www.cnblogs.com/matong/p/easy-database-executing-log-in-minute-level.html
Copyright © 2020-2023  润新知