mssql 监控磁盘空间告警实现方法

2016-02-19 09:47 4 1 收藏

下面图老师小编跟大家分享一个简单易学的mssql 监控磁盘空间告警实现方法教程,get新技能是需要行动的,喜欢的朋友赶紧收藏起来学习下吧!

【 tulaoshi.com - 编程语言 】

这几天突然有个想法:希望能够自动监控、收集数据库服务器的磁盘容量信息,当达到一个阀值后,自动发送告警邮件给DBA,将数据库磁盘详细信息告知DBA,提醒DBA做好存储规划计划,初步的想法是通过作业调用存储过程来实现(每天调用一次),这样避免了我每天每台数据库服务器都上去检查一下,尤其是手头的数据库服务器N多的情况,这样可以避免我每天浪费无谓的时间。如果大家有更好的建议和方法,欢迎指点一二,我整理、修改了三个存储过程如下:

存储过程1:SP_DiskCapacityAlert1.prc

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

说明:需要通过调用OLE 自动存储过程获取磁盘信息,而这些组件,基于服务器的安全配置,通常是禁用的,我们在存储过程通过sp_configure开启这个服务,调用服务完毕后,又通过sp_configure禁用该服务。另外,数据库服务器都位于内网,因此安全问题应该不大。

代码如下:

USE master;
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

 

IF EXISTS (SELECT 1 FROM dbo.sysobjects WHERE id = OBJECT_ID(N'sp_diskcapacity_alert1') AND OBJECTPROPERTY(id, 'IsProcedure') =1)
    DROP PROCEDURE sp_diskcapacity_alert1;
GO

--==================================================================================================================
--        ProcedureName        :            sp_diskcapacity_alert1
--        Author               :            Kerry   
--        CreateDate           :            2013-05-02
--        Description          :            获取数据库所在服务器的磁盘容量,当达到阀值是,发送告警邮件,提醒DBA做好存储规划计划
/******************************************************************************************************************
    Modified Date        Modified User        Version                    Modified Reason
    2013-05-6               Kerry            V01.00.00          修改HTML输出样式.以及磁盘容量输出改为GB
*******************************************************************************************************************/
--==================================================================================================================
CREATE PROCEDURE [dbo].[sp_diskcapacity_alert1]
(
        @Threshold    NUMERIC
)
AS

SET NOCOUNT ON

 
DECLARE @Result                INT;
DECLARE @objectInfo            INT;
DECLARE @DriveInfo             CHAR(1);
DECLARE @TotalSize             VARCHAR(20);
DECLARE @OutDrive              INT;
DECLARE @UnitMB                BIGINT;
DECLARE @HtmlContent           NVARCHAR(MAX) ;
DECLARE @FreeRat               NUMERIC;
DECLARE @EmailHead             VARCHAR(120);
SET @UnitMB = 1048576;

 

 
--创建临时表保存服务器磁盘容量信息
CREATE TABLE #DiskCapacity
(
    [DiskCD]        CHAR(1) ,
    FreeSize        INT        ,
    TotalSize       INT       
);

INSERT #DiskCapacity
        ([DiskCD], FreeSize )
EXEC master.dbo.xp_fixeddrives;

EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE;

EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE WITH OVERRIDE;

 
EXEC @Result = master.sys.sp_OACreate 'Scripting.FileSystemObject',@objectInfo OUT;

DECLARE CR_DiskInfo CURSOR LOCAL FAST_FORWARD
FOR SELECT  DiskCD FROM #DiskCapacity
ORDER by DiskCD

OPEN CR_DiskInfo;

FETCH NEXT FROM CR_DiskInfo INTO @DriveInfo

WHILE @@FETCH_STATUS=0
BEGIN

    EXEC @Result = sp_OAMethod @objectInfo,'GetDrive', @OutDrive OUT, @DriveInfo

 
    EXEC @Result = sp_OAGetProperty @OutDrive,'TotalSize', @TotalSize OUT

 
    UPDATE #DiskCapacity
    SET TotalSize=@TotalSize/@UnitMB
    WHERE DiskCD=@DriveInfo

    FETCH NEXT FROM CR_DiskInfo INTO @DriveInfo

END

CLOSE CR_DiskInfo
DEALLOCATE CR_DiskInfo;

EXEC @Result=sp_OADestroy @objectInfo

EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE;

EXEC sp_configure 'Ole Automation Procedures', 0;
RECONFIGURE WITH OVERRIDE;

EXEC sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE;

SELECT @FreeRat =FreeRate
FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY FreeSize / ( TotalSize * 1.0 ) ASC) AS RowIndex,
               CAST(( FreeSize / ( TotalSize * 1.0 ) ) * 100.0 AS INT)          AS FreeRate 

        FROM    #DiskCapacity
     ) T
WHERE RowIndex = 1;

    IF @FreeRat = @Threshold
        BEGIN

        IF @FreeRat 10 AND @FreeRat =20
            SET @EmailHead ='数据库磁盘容量告警(告警级别3)'
        ELSE IF @FreeRat =5 AND @FreeRat =10
            SET @EmailHead ='数据库磁盘容量告警(告警级别4)'
        ELSE
            SET @EmailHead ='数据库磁盘容量告警(告警级别5)'

        SET @HtmlContent =
            +   N'html'
            +   N'style type="text/css"'
            +   N' td {border:solid #9ec9ec;  border-width:0px 1px 1px 0px; padding:4px 0px;}'
            +   N' table {border:1px solid #9ec9ec; width:100%;border-width:1px 0px 0px 1px;text-align:center;font-size:12px}'
            +   N'/style'
            +   N'H1 style="color:#FF0000; text-align:center;font-size:14px"' + @EmailHead +'/H1'   
            +   N'table  '   
            +   N'trth磁盘盘符/thth总大小(GB)/thth已用空间(GB)/thth剩余空间(GB)/th'    
            +   N'th已用比例(%)/thth剩余比例(%)/th/tr ' +   
            CAST ( ( SELECT
            td =  DiskCD                                                , '',
            td = STR(TotalSize*1.0/1024,6,2)                            , '', 
            td = STR((TotalSize - FreeSize)*1.0/1024,6,2)               , '',                         
            td = STR(FreeSize*1.0/1024,6,2)                             , '',   
            td = STR(( TotalSize - FreeSize)*1.0/(TotalSize)* 100.0,6,2), '',        
            td = STR(( FreeSize * 1.0/ ( TotalSize  ) ) * 100.0,6,2)    , ''             
            FROM #DiskCapacity
            FOR XML PATH('tr'), TYPE     ) AS NVARCHAR(MAX) ) +     N'/table/html' ;

        

         EXEC msdb.dbo.sp_send_dbmail    
            @profile_name = 'DataBase_DDL_Event',    --指定你自己的profile_name   
            @recipients='****@163.com',                --指定你要发送到的邮箱
            @subject = '服务器磁盘空间告警',    
            @body = @HtmlContent,  
            @body_format = 'HTML' ;
        END

   
DROP TABLE #DiskCapacity;

RETURN;

GO

存储过程2:SP_DiskCapacityAlert2.prc

说明:需要启用xp_cmdshell来获取磁盘信息,关于xp_cmdshell安全隐患,一般该功能都是禁用的。

代码如下:

USE [master]
GO

 
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF OBJECT_ID(N'dbo.sp_diskcapacity_alert2') IS NOT NULL
    DROP PROCEDURE dbo.sp_diskcapacity_alert2;

GO

--==================================================================================================================
--        ProcedureName        :            sp_diskcapacity_alert2
--        Author               :            Kerry   
--        CreateDate           :            2013-05-02
--        Description          :            获取数据库所在服务器的磁盘容量,当达到阀值时,发送告警邮件,提醒DBA做好存储规划计划
/******************************************************************************************************************
    Modified Date        Modified User        Version                    Modified Reason
    2013-05-6             Kerry                 V01.00.00                修改HTML输出样式.以及磁盘容量输出改为GB
*******************************************************************************************************************/
--==================================================================================================================
CREATE PROCEDURE [dbo].[sp_diskcapacity_alert2]
(
        @Threshold    NUMERIC
)

AS
BEGIN

SET NOCOUNT ON;

DECLARE @HtmlContent    NVARCHAR(MAX) ;
DECLARE @FreeRat        NUMERIC;
DECLARE @EmailHead        VARCHAR(200);

--创建临时表保存服务器磁盘容量信息
CREATE TABLE #DiskCapacity
(
    DiskCD            CHAR(4) ,
    FreeSize         INT        ,
    TotalSize         BIGINT       
);

INSERT INTO #DiskCapacity
        ( DiskCD, FreeSize )
EXEC master..xp_fixeddrives;

 

EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
EXEC sp_configure 'show advanced options', 0
RECONFIGURE

 
CREATE TABLE #DriveInfo1(ID INT IDENTITY(1,1),DiskCD VARCHAR(12));

INSERT INTO #DriveInfo1(DiskCD)
EXEC xp_cmdshell 'wmic LOGICALDISK get name';

 
CREATE TABLE #DriveInfo2(ID INT IDENTITY(1,1), TotalSize VARCHAR(22));

INSERT INTO #DriveInfo2
        ( TotalSize )
EXEC  xp_cmdshell 'wmic LOGICALDISK get size';

 
DELETE FROM #DriveInfo1 WHERE ID=1;
DELETE FROM #DriveInfo2 WHERE ID=1;

 
UPDATE #DriveInfo1 SET DiskCD = REPLACE(DiskCD,':','');
SELECT * FROM #DiskCapacity

UPDATE #DiskCapacity  SET TotalSize =(SELECT CAST(LEFT(N.TotalSize, LEN(N.TotalSize)-1) AS BIGINT)/1024/1024 FROM #DriveInfo1 M INNER JOIN #DriveInfo2 N ON M.ID = N.ID
WHERE M.DiskCD IS NOT NULL AND LEN(M.DiskCD) 1 AND #DiskCapacity.DiskCD = LEFT(M.DiskCD, LEN(M.DiskCD)-1))

  SELECT * FROM #DiskCapacity

EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE
EXEC sp_configure 'show advanced options', 0
RECONFIGURE

SELECT @FreeRat =FreeRate
FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY FreeSize / ( TotalSize * 1.0 ) ASC) AS RowIndex,
               CAST(( FreeSize / ( TotalSize * 1.0 ) ) * 100.0 AS INT)     AS FreeRate 

        FROM    #DiskCapacity
     ) T
WHERE RowIndex = 1;

    IF @FreeRat = @Threshold
        BEGIN

        IF @FreeRat 10 AND @FreeRat =20
            SET @EmailHead ='数据库磁盘容量告警(告警级别3)'
        ELSE IF @FreeRat =5 AND @FreeRat =10
            SET @EmailHead ='数据库磁盘容量告警(告警级别4)'
        ELSE
            SET @EmailHead ='数据库磁盘容量告警(告警级别5)'

        SET @HtmlContent =
            +   N'html'
            +   N'style type="text/css"'
            +   N' td {border:solid #9ec9ec;  border-width:0px 1px 1px 0px; padding:4px 0px;}'
            +   N' table {border:1px solid #9ec9ec; width:100%;border-width:1px 0px 0px 1px;text-align:center;font-size:12px}'
            +   N'/style'
            +   N'H1 style="color:#FF0000; text-align:center;font-size:14px"' + @EmailHead +'/H1'   
            +   N'table  '   
            +   N'trth磁盘盘符/thth总大小(GB)/thth已用空间(GB)/thth剩余空间(GB)/th'    
            +   N'th已用比例(%)/thth剩余比例(%)/th/tr ' +   
            CAST ( ( SELECT
            td =  DiskCD                                                , '',
            td = STR(TotalSize*1.0/1024,6,2)                            , '', 
            td = STR((TotalSize - FreeSize)*1.0/1024,6,2)               , '',                         
            td = STR(FreeSize*1.0/1024,6,2)                             , '',   
            td = STR(( TotalSize - FreeSize)*1.0/(TotalSize)* 100.0,6,2), '',        
            td = STR(( FreeSize * 1.0/ ( TotalSize  ) ) * 100.0,6,2)    , ''             
            FROM #DiskCapacity
            FOR XML PATH('tr'), TYPE     ) AS NVARCHAR(MAX) ) +     N'/table/html' ;

        

         EXEC msdb.dbo.sp_send_dbmail    
            @profile_name = 'DataBase_DDL_Event', --指定你自己的profile_name      
            @recipients='konglb@***.com',         --指定你要发送到的邮箱
            @subject = '服务器磁盘空间告警',    
            @body = @HtmlContent,  
            @body_format = 'HTML' ;
        END
END 
GO

存储过程3:SP_DiskCapacityAlert3.prc

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

说明:这个存储过程不用上面两个有安全隐患的存储过程,但是获取不到磁盘的总体信息,就不能通过一个阀值来告警,只能设置当磁盘剩余多少空间时,产生告警邮件。

代码如下:

USE [master]
GO

 
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF OBJECT_ID(N'dbo.sp_diskcapacity_alert3') IS NOT NULL
    DROP PROCEDURE dbo.sp_diskcapacity_alert3;

GO

--==================================================================================================================
--        ProcedureName        :            sp_diskcapacity_alert3
--        Author               :            Kerry   
--        CreateDate           :            2013-05-02
--        Description          :            获取数据库所在服务器的磁盘容量,当某个磁盘剩余容量低于某个值时,发送告警邮件,
--                                          提醒DBA做好存储规划计划
/******************************************************************************************************************
    Modified Date        Modified User        Version                    Modified Reason
    2013-05-6                Kerry          V01.00.00           修改HTML输出样式.以及磁盘容量输出改为GB
*******************************************************************************************************************/
--==================================================================================================================
CREATE PROCEDURE [dbo].[sp_diskcapacity_alert3]
(
        @DiskCapacity    FLOAT
)

AS
BEGIN

DECLARE @FreeSize         INT;
DECLARE @EmailHead        VARCHAR(200);
DECLARE @HtmlContent      NVARCHAR(MAX) ;

 
--创建临时表保存服务器磁盘容量信息
CREATE TABLE #DiskCapacity
(
    DiskCD            CHAR(4) ,
    FreeSize        INT           
);

INSERT INTO #DiskCapacity
        ( DiskCD, FreeSize )
EXEC master..xp_fixeddrives;

SELECT  @FreeSize = FreeSize*1.0/1024
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY FreeSize ASC ) AS RowIndex ,
                    FreeSize AS FreeSize
          FROM      #DiskCapacity
        ) T
WHERE   RowIndex = 1 ;

SELECT FreeSize*1.0/1024 FROM  #DiskCapacity;
  IF @FreeSize = @DiskCapacity
    BEGIN

        IF @FreeSize 1
            AND @FreeSize = 2
            SET @EmailHead = '数据库磁盘容量告警(告警级别3)'
        ELSE
            IF @FreeSize = 0.5
                AND @FreeSize = 1
                SET @EmailHead = '数据库磁盘容量告警(告警级别4)'
            ELSE
                SET @EmailHead = '数据库磁盘容量告警(告警级别5)'

        SET @HtmlContent = +N'html' + N'style type="text/css"'
            + N' td {border:solid #9ec9ec;  border-width:0px 1px 1px 0px; padding:4px 0px;}'
            + N' table {border:1px solid #9ec9ec; width:100%;border-width:1px 0px 0px 1px;text-align:center;font-size:12px}'
            + N'/style'
            + N'H1 style="color:#FF0000; text-align:center;font-size:14px"'
            + @EmailHead + '/H1' + N'table  '
            + N'trth磁盘盘符/thth剩余空间(GB)/th' + N'/tr '
            + CAST(( SELECT td = DiskCD ,
                            '' ,
                            td = STR(FreeSize * 1.0 / 1024, 6, 2) ,
                            ''
                     FROM   #DiskCapacity
                   FOR
                     XML PATH('tr') ,
                         TYPE
                   ) AS NVARCHAR(MAX)) + N'/table/html' ;

           EXEC msdb.dbo.sp_send_dbmail    
            @profile_name = 'DataBase_DDL_Event',  --指定你自己的profile_name  
            @recipients='konglb@***.com',          --指定你要发送到的邮箱
              @subject = '服务器磁盘空间告警',    
            @body = @HtmlContent,  
            @body_format = 'HTML' ;

    END

END
GO

作者:潇湘隐者
出处:http://www.cnblogs.com/kerrycode/

来源:https://www.tulaoshi.com/n/20160219/1592146.html

延伸阅读
标签: windows 操作系统
概要 当基于 Windows XP 的计算机在磁盘空间较少的情况下运行时,您单击“磁盘清理向导”,将其启动后,会收到“Low Disk Space”(磁盘空间不足)消息。本文介绍了您会看到“Low Disk Space”(磁盘空间不足)消息的情况。 更多信息 警告:“注册表编辑器”使用不当可导致严重问题,可能需要重新安装操作系统。Microsoft 不能保证您可以解...
标签: 电脑入门
安装Windows 8 C盘要分配多大空间? 在安装Windows 8之前,要为其划分多大的系统磁盘空间,是首先要考虑的重要因素,因为系统卷如果划分空间过多则会浪费磁盘资源,过少,而又会因为与日俱增的系统文件而导致系统盘空间不够用,带来不必要的麻烦。那我们安装Windows 8 ,到底需要多大的磁盘空间为妙呢? 微软官方建议: 安装Windows 8(x86) ...
标签: 电脑入门
系统是Windows XP,最近我的系统盘空间只剩下了200MB,删除一些文件后系统就不会再提示低空间了,不知有没有什么方法可以取消系统自动提示磁盘空间低? 这个可以通过修改注册表来达到目的:打开注册表编辑器,依次展开:[HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer]分支,然后在右侧窗口中新建名称为NoLo...
  原始文件:Linux Quota mini-HOWTO 档案叙述:磁碟空间限制简易使用说明 翻译日期:1996/09/20 1997/10/21 翻译维护:asdchen@ms1.hinet.net 修 订:cwhuang@phys.ntu.edu.tw (1997/10/21) ------------------------------------------------------...
标签: 电脑入门
查看Linux磁盘空间的工具有很多,那么怎么使用命令来查看磁盘空间呢?那就要用到df命令了,下面图老师小编给大家介绍下使用df命令查看Linux磁盘空间的方法。 [root@localhost ~]# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda2 14G 11G 2.6G 82% / /dev/sda1 99M 14M 81M 14% /boot tmpfs 442M 275M 168M 63% /dev/shm /de...

经验教程

635

收藏

77
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部