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

存储过程1:SP_DiskCapacityAlert1.prc

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

  1. USE master;
  1. GO
  1.  
  1. SET ANSI_NULLS ON
  1. GO
  1.  
  1. SET QUOTED_IDENTIFIER ON
  1. GO
  1.  
  1.  
  1.  
  1. IF EXISTS (SELECT 1 FROM dbo.sysobjects WHERE id = OBJECT_ID(N'sp_diskcapacity_alert1') AND OBJECTPROPERTY(id, 'IsProcedure') =1)
  1. DROP PROCEDURE sp_diskcapacity_alert1;
  1. GO
  1.  
  1. --==================================================================================================================
  1. -- ProcedureName : sp_diskcapacity_alert1
  1. -- Author : Kerry
  1. -- CreateDate : 2013-05-02
  1. -- Description : 获取数据库所在服务器的磁盘容量,当达到阀值是,发送告警邮件,提醒DBA做好存储规划计划
  1. /******************************************************************************************************************
  1. Modified Date Modified User Version Modified Reason
  1. 2013-05-6 Kerry V01.00.00 修改HTML输出样式.以及磁盘容量输出改为GB
  1. *******************************************************************************************************************/
  1. --==================================================================================================================
  1. CREATE PROCEDURE [dbo].[sp_diskcapacity_alert1]
  1. (
  1. @Threshold NUMERIC
  1. )
  1. AS
  1.  
  1. SET NOCOUNT ON
  1.  
  1.  
  1. DECLARE @Result INT;
  1. DECLARE @objectInfo INT;
  1. DECLARE @DriveInfo CHAR(1);
  1. DECLARE @TotalSize VARCHAR(20);
  1. DECLARE @OutDrive INT;
  1. DECLARE @UnitMB BIGINT;
  1. DECLARE @HtmlContent NVARCHAR(MAX) ;
  1. DECLARE @FreeRat NUMERIC;
  1. DECLARE @EmailHead VARCHAR(120);
  1. SET @UnitMB = 1048576;
  1.  
  1.  
  1.  
  1.  
  1. --创建临时表保存服务器磁盘容量信息
  1. CREATE TABLE #DiskCapacity
  1. (
  1. [DiskCD] CHAR(1) ,
  1. FreeSize INT ,
  1. TotalSize INT
  1. );
  1.  
  1. INSERT #DiskCapacity
  1. ([DiskCD], FreeSize )
  1. EXEC master.dbo.xp_fixeddrives;
  1. EXEC sp_configure 'show advanced options', 1
  1. RECONFIGURE WITH OVERRIDE;
  1.  
  1. EXEC sp_configure 'Ole Automation Procedures', 1;
  1. RECONFIGURE WITH OVERRIDE;
  1.  
  1.  
  1. EXEC @Result = master.sys.sp_OACreate 'Scripting.FileSystemObject',@objectInfo OUT;
  1.  
  1. DECLARE CR_DiskInfo CURSOR LOCAL FAST_FORWARD
  1. FOR SELECT DiskCD FROM #DiskCapacity
  1. ORDER by DiskCD
  1.  
  1. OPEN CR_DiskInfo;
  1.  
  1. FETCH NEXT FROM CR_DiskInfo INTO @DriveInfo
  1.  
  1. WHILE @@FETCH_STATUS=0
  1. BEGIN
  1.  
  1. EXEC @Result = sp_OAMethod @objectInfo,'GetDrive', @OutDrive OUT, @DriveInfo
  1.  
  1.  
  1. EXEC @Result = sp_OAGetProperty @OutDrive,'TotalSize', @TotalSize OUT
  1.  
  1.  
  1. UPDATE #DiskCapacity
  1. SET TotalSize=@TotalSize/@UnitMB
  1. WHERE DiskCD=@DriveInfo
  1.  
  1. FETCH NEXT FROM CR_DiskInfo INTO @DriveInfo
  1.  
  1. END
  1.  
  1. CLOSE CR_DiskInfo
  1. DEALLOCATE CR_DiskInfo;
  1.  
  1. EXEC @Result=sp_OADestroy @objectInfo
  1.  
  1. EXEC sp_configure 'show advanced options', 1
  1. RECONFIGURE WITH OVERRIDE;
  1.  
  1. EXEC sp_configure 'Ole Automation Procedures', 0;
  1. RECONFIGURE WITH OVERRIDE;
  1.  
  1. EXEC sp_configure 'show advanced options', 0
  1. RECONFIGURE WITH OVERRIDE;
  1.  
  1. SELECT @FreeRat =FreeRate
  1. FROM (
  1. SELECT ROW_NUMBER() OVER (ORDER BY FreeSize / ( TotalSize * 1.0 ) ASC) AS RowIndex,
  1. CAST(( FreeSize / ( TotalSize * 1.0 ) ) * 100.0 AS INT) AS FreeRate
  1. FROM #DiskCapacity
  1. ) T
  1. WHERE RowIndex = 1;
  1.  
  1. IF @FreeRat <= @Threshold
  1. BEGIN
  1. IF @FreeRat > 10 AND @FreeRat <=20
  1. SET @EmailHead ='数据库磁盘容量告警(告警级别3)'
  1. ELSE IF @FreeRat >=5 AND @FreeRat <=10
  1. SET @EmailHead ='数据库磁盘容量告警(告警级别4)'
  1. ELSE
  1. SET @EmailHead ='数据库磁盘容量告警(告警级别5)'
  1. SET @HtmlContent =
  1. + N'<html>'
  1. + N'<style type="text/css">'
  1. + N' td {border:solid #9ec9ec; border-width:0px 1px 1px 0px; padding:4px 0px;}'
  1. + N' table {border:1px solid #9ec9ec; width:100%;border-width:1px 0px 0px 1px;text-align:center;font-size:12px}'
  1. + N'</style>'
  1. + N'<H1 style="color:#FF0000; text-align:center;font-size:14px">' + @EmailHead +'</H1>'
  1. + N'<table >'
  1. + N'<tr><th>磁盘盘符</th><th>总大小(GB)</th><th>已用空间(GB)</th><th>剩余空间(GB)</th>'
  1. + N'<th>已用比例(%)</th><th>剩余比例(%)</th></tr >' +
  1. CAST ( ( SELECT
  1. td = DiskCD , '',
  1. td = STR(TotalSize*1.0/1024,6,2) , '',
  1. td = STR((TotalSize - FreeSize)*1.0/1024,6,2) , '',
  1. td = STR(FreeSize*1.0/1024,6,2) , '',
  1. td = STR(( TotalSize - FreeSize)*1.0/(TotalSize)* 100.0,6,2), '',
  1. td = STR(( FreeSize * 1.0/ ( TotalSize ) ) * 100.0,6,2) , ''
  1. FROM #DiskCapacity
  1. FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table></html>' ;
  1. EXEC msdb.dbo.sp_send_dbmail
  1. @profile_name = 'DataBase_DDL_Event', --指定你自己的profile_name
  1. @recipients='****@163.com', --指定你要发送到的邮箱
  1. @subject = '服务器磁盘空间告警',
  1. @body = @HtmlContent,
  1. @body_format = 'HTML' ;
  1. END
  1.  
  1. DROP TABLE #DiskCapacity;
  1.  
  1. RETURN;
  1.  
  1. GO
  1.  
  1.  

存储过程2:SP_DiskCapacityAlert2.prc

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

  1. USE [master]
  1. GO
  1. SET ANSI_NULLS ON
  1. GO
  1. SET QUOTED_IDENTIFIER ON
  1. GO
  1. IF OBJECT_ID(N'dbo.sp_diskcapacity_alert2') IS NOT NULL
  1. DROP PROCEDURE dbo.sp_diskcapacity_alert2;
  1. GO
  1. --==================================================================================================================
  1. -- ProcedureName : sp_diskcapacity_alert2
  1. -- Author : Kerry
  1. -- CreateDate : 2013-05-02
  1. -- Description : 获取数据库所在服务器的磁盘容量,当达到阀值时,发送告警邮件,提醒DBA做好存储规划计划
  1. /******************************************************************************************************************
  1. Modified Date Modified User Version Modified Reason
  1. 2013-05-6 Kerry V01.00.00 修改HTML输出样式.以及磁盘容量输出改为GB
  1. *******************************************************************************************************************/
  1. --==================================================================================================================
  1. CREATE PROCEDURE [dbo].[sp_diskcapacity_alert2]
  1. (
  1. @Threshold NUMERIC
  1. )
  1. AS
  1. BEGIN
  1. SET NOCOUNT ON;
  1. DECLARE @HtmlContent NVARCHAR(MAX) ;
  1. DECLARE @FreeRat NUMERIC;
  1. DECLARE @EmailHead VARCHAR(200);
  1. --创建临时表保存服务器磁盘容量信息
  1. CREATE TABLE #DiskCapacity
  1. (
  1. DiskCD CHAR(4) ,
  1. FreeSize  INT ,
  1. TotalSize BIGINT
  1. );
  1. INSERT INTO #DiskCapacity
  1. ( DiskCD, FreeSize )
  1. EXEC master..xp_fixeddrives;
  1. EXEC sp_configure 'show advanced options', 1
  1. RECONFIGURE
  1. EXEC sp_configure 'xp_cmdshell', 1
  1. RECONFIGURE
  1. EXEC sp_configure 'show advanced options', 0
  1. RECONFIGURE
  1. CREATE TABLE #DriveInfo1(ID INT IDENTITY(1,1),DiskCD VARCHAR(12));
  1. INSERT INTO #DriveInfo1(DiskCD)
  1. EXEC xp_cmdshell 'wmic LOGICALDISK get name';
  1. CREATE TABLE #DriveInfo2(ID INT IDENTITY(1,1), TotalSize VARCHAR(22));
  1. INSERT INTO #DriveInfo2
  1. ( TotalSize )
  1. EXEC xp_cmdshell 'wmic LOGICALDISK get size';
  1. DELETE FROM #DriveInfo1 WHERE ID=1;
  1. DELETE FROM #DriveInfo2 WHERE ID=1;
  1. UPDATE #DriveInfo1 SET DiskCD = REPLACE(DiskCD,':','');
  1. SELECT * FROM #DiskCapacity
  1. 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
  1. WHERE M.DiskCD IS NOT NULL AND LEN(M.DiskCD) >1 AND #DiskCapacity.DiskCD = LEFT(M.DiskCD, LEN(M.DiskCD)-1))
  1. SELECT * FROM #DiskCapacity
  1. EXEC sp_configure 'show advanced options', 1
  1. RECONFIGURE
  1. EXEC sp_configure 'xp_cmdshell', 0
  1. RECONFIGURE
  1. EXEC sp_configure 'show advanced options', 0
  1. RECONFIGURE
  1. SELECT @FreeRat =FreeRate
  1. FROM (
  1. SELECT ROW_NUMBER() OVER (ORDER BY FreeSize / ( TotalSize * 1.0 ) ASC) AS RowIndex,
  1. CAST(( FreeSize / ( TotalSize * 1.0 ) ) * 100.0 AS INT) AS FreeRate
  1. FROM #DiskCapacity
  1. ) T
  1. WHERE RowIndex = 1;
  1. IF @FreeRat <= @Threshold
  1. BEGIN
  1. IF @FreeRat > 10 AND @FreeRat <=20
  1. SET @EmailHead ='数据库磁盘容量告警(告警级别3)'
  1. ELSE IF @FreeRat >=5 AND @FreeRat <=10
  1. SET @EmailHead ='数据库磁盘容量告警(告警级别4)'
  1. ELSE
  1. SET @EmailHead ='数据库磁盘容量告警(告警级别5)'
  1. SET @HtmlContent =
  1. + N'<html>'
  1. + N'<style type="text/css">'
  1. + N' td {border:solid #9ec9ec; border-width:0px 1px 1px 0px; padding:4px 0px;}'
  1. + N' table {border:1px solid #9ec9ec; width:100%;border-width:1px 0px 0px 1px;text-align:center;font-size:12px}'
  1. + N'</style>'
  1. + N'<H1 style="color:#FF0000; text-align:center;font-size:14px">' + @EmailHead +'</H1>'
  1. + N'<table >'
  1. + N'<tr><th>磁盘盘符</th><th>总大小(GB)</th><th>已用空间(GB)</th><th>剩余空间(GB)</th>'
  1. + N'<th>已用比例(%)</th><th>剩余比例(%)</th></tr >' +
  1. CAST ( ( SELECT
  1. td = DiskCD , '',
  1. td = STR(TotalSize*1.0/1024,6,2) , '',
  1. td = STR((TotalSize - FreeSize)*1.0/1024,6,2) , '',
  1. td = STR(FreeSize*1.0/1024,6,2) , '',
  1. td = STR(( TotalSize - FreeSize)*1.0/(TotalSize)* 100.0,6,2), '',
  1. td = STR(( FreeSize * 1.0/ ( TotalSize ) ) * 100.0,6,2) , ''
  1. FROM #DiskCapacity
  1. FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table></html>' ;
  1. EXEC msdb.dbo.sp_send_dbmail
  1. @profile_name = 'DataBase_DDL_Event', --指定你自己的profile_name
  1. @recipients='konglb@***.com', --指定你要发送到的邮箱
  1. @subject = '服务器磁盘空间告警',
  1. @body = @HtmlContent,
  1. @body_format = 'HTML' ;
  1. END
  1. END
  1. GO

存储过程3:SP_DiskCapacityAlert2.prc

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

  1. USE [master]
  1. GO
  1. SET ANSI_NULLS ON
  1. GO
  1. SET QUOTED_IDENTIFIER ON
  1. GO
  1. IF OBJECT_ID(N'dbo.sp_diskcapacity_alert3') IS NOT NULL
  1. DROP PROCEDURE dbo.sp_diskcapacity_alert3;
  1. GO
  1. --==================================================================================================================
  1. -- ProcedureName : sp_diskcapacity_alert3
  1. -- Author : Kerry
  1. -- CreateDate : 2013-05-02
  1. -- Description : 获取数据库所在服务器的磁盘容量,当某个磁盘剩余容量低于某个值时,发送告警邮件,
  1. -- 提醒DBA做好存储规划计划
  1. /******************************************************************************************************************
  1. Modified Date Modified User Version Modified Reason
  1. 2013-05-6 Kerry V01.00.00 修改HTML输出样式.以及磁盘容量输出改为GB
  1. *******************************************************************************************************************/
  1. --==================================================================================================================
  1. CREATE PROCEDURE [dbo].[sp_diskcapacity_alert3]
  1. (
  1. @DiskCapacity FLOAT
  1. )
  1. AS
  1. BEGIN
  1. DECLARE @FreeSize INT;
  1. DECLARE @EmailHead VARCHAR(200);
  1. DECLARE @HtmlContent NVARCHAR(MAX) ;
  1. --创建临时表保存服务器磁盘容量信息
  1. CREATE TABLE #DiskCapacity
  1. (
  1. DiskCD CHAR(4) ,
  1. FreeSize INT
  1. );
  1. INSERT INTO #DiskCapacity
  1. ( DiskCD, FreeSize )
  1. EXEC master..xp_fixeddrives;
  1. SELECT @FreeSize = FreeSize*1.0/1024
  1. FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY FreeSize ASC ) AS RowIndex ,
  1. FreeSize AS FreeSize
  1. FROM #DiskCapacity
  1. ) T
  1. WHERE RowIndex = 1 ;
  1. SELECT FreeSize*1.0/1024 FROM #DiskCapacity;
  1. IF @FreeSize <= @DiskCapacity
  1. BEGIN
  1. IF @FreeSize > 1
  1. AND @FreeSize <= 2
  1. SET @EmailHead = '数据库磁盘容量告警(告警级别3)'
  1. ELSE
  1. IF @FreeSize >= 0.5
  1. AND @FreeSize <= 1
  1. SET @EmailHead = '数据库磁盘容量告警(告警级别4)'
  1. ELSE
  1. SET @EmailHead = '数据库磁盘容量告警(告警级别5)'
  1. SET @HtmlContent = +N'<html>' + N'<style type="text/css">'
  1. + N' td {border:solid #9ec9ec; border-width:0px 1px 1px 0px; padding:4px 0px;}'
  1. + N' table {border:1px solid #9ec9ec; width:100%;border-width:1px 0px 0px 1px;text-align:center;font-size:12px}'
  1. + N'</style>'
  1. + N'<H1 style="color:#FF0000; text-align:center;font-size:14px">'
  1. + @EmailHead + '</H1>' + N'<table >'
  1. + N'<tr><th>磁盘盘符</th><th>剩余空间(GB)</th>' + N'</tr >'
  1. + CAST(( SELECT td = DiskCD ,
  1. '' ,
  1. td = STR(FreeSize * 1.0 / 1024, 6, 2) ,
  1. ''
  1. FROM #DiskCapacity
  1. FOR
  1. XML PATH('tr') ,
  1. TYPE
  1. ) AS NVARCHAR(MAX)) + N'</table></html>' ;
  1. EXEC msdb.dbo.sp_send_dbmail
  1. @profile_name = 'DataBase_DDL_Event', --指定你自己的profile_name
  1. @recipients='konglb@***.com', --指定你要发送到的邮箱
  1. @subject = '服务器磁盘空间告警',
  1. @body = @HtmlContent,
  1. @body_format = 'HTML' ;
  1. END
  1. END
  1. GO

MS SQL 监控磁盘空间告警的更多相关文章

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

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

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

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

  3. sql查询磁盘空间并发预警邮件

    检测磁盘空间,如果低于设置的预警值则发出一封预警邮件,这样的事情可以用SQL server的作业可以做,关键SQL语句如下例子所示: DECLARE @TableText NVARCHAR(MAX)= ...

  4. Linux下监控磁盘空间的四个命令

    无论是运行简单的Linux桌面还是大型Linux服务器,都需要了解可供应用程序使用的空间,并跟踪系统的磁盘使用情况.下面介绍四个核心命令行命令来管理Linux系统上的介质环境. 一.mount命令 m ...

  5. MS SQL 监控错误日志的告警信息

    SQL Server的错误消息(Error Message)按照消息的严重级别一共划分25个等级,级别越高,表示严重性也越高.但是如果你统计sys.messages,你会发现,实际上只有16(SQL ...

  6. [Linux监控]磁盘空间大小

    echo 192.168.10.69>>ip.list ------------------------------------------- #!/bin/bash #注意if和[]之间 ...

  7. Linux磁盘空间监控告警

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

  8. (转)Linux磁盘空间监控告警 && Linux磁盘管理

    Linux磁盘空间监控告警 http://blog.csdn.net/github_39069288/article/details/73478784-----------Linux磁盘管理 原文:h ...

  9. SQL Server 死锁的告警监控

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

随机推荐

  1. JAVA处理Http请求(GET,POST)

    本文用的是java.net里面的方法,HttpClient也可以. java.net.HttpURLConnection java.net.URL 1. GET public static Strin ...

  2. MySQL两阶段提交

    参数介绍 innodb_flush_log_at_trx_commit 0: 每隔1s,系统后台线程刷log buffer,也就是把redo日志刷盘,这里会调用fsync,所以可能丢失最后1s的事务. ...

  3. 使用Android-PullToRefresh实现下拉刷新功能

    源代码:https://github.com/chrisbanes/Android-PullToRefresh 一. 导入类库 将Library文件夹作为Android项目Import到Eclipse ...

  4. Java与算法之(13) - 二叉搜索树

    查找是指在一批记录中找出满足指定条件的某一记录的过程,例如在数组{ 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15 }中查找数字15,实现代码很简单 ...

  5. See you~(二维树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1892 See you~ Time Limit: 5000/3000 MS (Java/Others)  ...

  6. Personal Learning Path of Java——Java语言基础

    Java语言是面向对象编程语言,Java程序的基本组成单元是类,类体中又包括属性和方法两部分.每一个程序都必须包含一个main()方法,含有main()方法的类称为主类. 如下面代码: package ...

  7. 在阿里云服务器上安装完成并启动Tomcat后,通过http不能访问--解决办法

    在阿里云服务器上安装完成并启动Tomcat后,通过http不能访问的原因是阿里云平台为了安全设置了安全组策略,必须我们授权的端口,其他计算机才能通过http访问 解决办法:(这里以阿里轻量应用服务器为 ...

  8. .30-浅析webpack源码之doResolve事件流(1)

    这里所有的插件都对应着一个小功能,画个图整理下目前流程: 上节是从ParsePlugin中出来,对'./input.js'入口文件的路径做了处理,返回如下: ParsePlugin.prototype ...

  9. Tomcat之URL查找的过程

    Tomcat之URL查找的过程     webapps目录: tomcat共享目录.需要共享的本地资源放到此目录中.  

  10. linux CentOS部署【minimal 】

    1.为什么选择CentOS不选择其他版本:http://www.cnblogs.com/TeemoHQ/p/6377260.html 2.准备的资源:VMware[官网下载],CentOS镜像 [阿里 ...