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

存储过程1:SP_DiskCapacityAlert1.prc

说明:需要通过调用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'<tr><th>磁盘盘符</th><th>总大小(GB)</th><th>已用空间(GB)</th><th>剩余空间(GB)</th>'     
            +   N'<th>已用比例(%)</th><th>剩余比例(%)</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'<tr><th>磁盘盘符</th><th>总大小(GB)</th><th>已用空间(GB)</th><th>剩余空间(GB)</th>'     
            +   N'<th>已用比例(%)</th><th>剩余比例(%)</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_DiskCapacityAlert2.prc

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

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'<tr><th>磁盘盘符</th><th>剩余空间(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

MS SQL 监控磁盘空间告警相关推荐

  1. MS SQL 监控数据/日志文件增长

        前几天,在所有数据库服务器部署了监控磁盘空间的存储过程和作业后(MS SQL 监控磁盘空间告警),今天突然收到了两封告警邮件,好吧,存储规划是一方面,但是,是不是要分析一下是什么原因造成磁盘空 ...

  2. SQL Server 磁盘空间告急(磁盘扩容)转载

    SQL Server 磁盘空间告急(磁盘扩容)转载 一.背景 在线上系统中,如果我们发现存放数据库文件的磁盘空间不够,我们应该怎么办呢?新买一个硬盘挂载上去可以嘛?(linux下可以直接挂载硬盘进行扩 ...

  3. linux下监控磁盘空间脚本

    Linux下监控磁盘的空闲空间的shell脚本,对于系统管理员或DBA来说,必不可少.下面是给出的一个监控磁盘空间空间shell脚本的样本. robin@SZDB:~/dba_scripts/cust ...

  4. CentOS 7实现SHEEL脚本监控磁盘空间达到指定阈值时发送邮件至指定邮箱

    实现需求:CentOS 7实现SHEEL脚本监控磁盘空间达到指定阈值时发送邮件至指定邮箱 操作环境:VWware下的CentOS 7.9 一.安装配置mailx CentOS 7自带mailx软件包, ...

  5. 工作小记-Linux磁盘空间告警

    环境介绍:Centos 6.3运行在ESXi 5.5中 分了两块虚拟磁盘,一块大小为IDE 20G,另外一块为SCSI 73G. lsb_release -a查看版本为CentOS release 6 ...

  6. Linux磁盘空间监控告警

    Linux系统中需要监控磁盘各分区的使用情 况,避免由于各种突发情况,造成磁盘空间被消耗殆尽的情况,例如某个分区被Oracle的归档日志耗尽,导致后续的日志文件无法归档,这时ORACLE数 据库就会出 ...

  7. SQL Server 死锁的告警监控

    原文:SQL Server 死锁的告警监控 今天这篇文章总结一下如何监控SQL Server的死锁,其实以前写过MS SQL 监控错误日志的告警信息,这篇文章着重介绍如何监控数据库的死锁,当然这篇文章 ...

  8. linux磁盘使用情况脚本,技术|用 Linux Shell 脚本来监控磁盘使用情况并发送邮件...

    市场上有很多用来监控 Linux 系统的监控工具,当系统到达阀值后它将发送一封邮件.它监控所有的东西例如 CPU 利用率.内存利用率.交换空间利用率.磁盘空间利用率等等.然而,它更适合小环境和大环境. ...

  9. 查询linux磁盘剩余空间脚本,linux磁盘空间报警脚本

    今天分享个简单的监控磁盘空间脚本.其实shell脚本写起来不难,关键是你有整个脚本的思路! 好.大概思路是这样: 我现在想要监控/分区的空间使用量,若超过10%的话,发送一个报警短信! 首先,我们要如 ...

最新文章

  1. 我被面试官问到的问题-5
  2. API编程基本控件使用
  3. gradle打包 执行类方法
  4. APNIC执委赵巍:IPv4向IPv6过渡再无退路
  5. java Servlet学习笔记(一)
  6. 我为何不再愿意打一份朝九晚五的工?
  7. 在脚本中, 使用sqlite3检查android程序生成的数据库是否OK
  8. 创建zookeeper客户端
  9. 解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:
  10. ADAMS搭建控制系统教程:偏心连杆机构的转速控制
  11. EasyRecovery2022版支持电脑, 硬盘, U盘, 内存卡, 回收站等设备数据恢复
  12. c语言编译是繁体字,cconv实现简体/繁体转换
  13. 图片外链网站需要什么样服务器,10个支持外链图片服务的免费图床网站
  14. Telnet + VTY(虚拟终端Virtual Teletype Terminal)远程管理路由器和交换机
  15. 震坤行工业超市研发效能提升之路 | 云效
  16. 给猜字游戏增加难度设置
  17. vue push html,html5 - Vue 2.0 javaScript 数组循环push json 对象问题
  18. Capture One 21 Pro v14.3.0.185 飞思顶级图像后期处理编辑软件
  19. Backtrack5 搭建Nessus
  20. Linux 驱动开发 四十三:platform 设备驱动实验(一)

热门文章

  1. 据说20%的业务能拿到外贸大订单因为懂这个方法
  2. torch.cuda.stream(stream)
  3. 机器学习基础——特征提取(笔记一)
  4. 破解爆款网文的问题,三步教你绘制大厂标准状态图(第一篇)
  5. 双十二购买护眼台灯亮度多少合适?灯光亮度多少对眼睛比较好呢
  6. 怎样linux部署web应用程序,Linux系统部署WEB项目(2020最新最详细)
  7. 贝叶斯理论,朴素贝叶斯算法
  8. Springboot下载excel文件中文名乱码问题
  9. 常量和变量的区别(正确认识)
  10. 装破解软件时如何暂时关掉Windows Defender防火墙,只需简单几步即可