MS SQL 监控磁盘空间告警
这几天突然有个想法:希望能够自动监控、收集数据库服务器的磁盘容量信息,当达到一个阀值后,自动发送告警邮件给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
GO
MS SQL 监控磁盘空间告警的更多相关文章
- MS SQL 监控数据/日志文件增长
前几天,在所有数据库服务器部署了监控磁盘空间的存储过程和作业后(MS SQL 监控磁盘空间告警),今天突然收到了两封告警邮件,好吧,存储规划是一方面,但是,是不是要分析一下是什么原因造成磁盘空 ...
- SQL Server 磁盘空间告急(磁盘扩容)转载
一.背景 在线上系统中,如果我们发现存放数据库文件的磁盘空间不够,我们应该怎么办呢?新买一个硬盘挂载上去可以嘛?(linux下可以直接挂载硬盘进行扩容),但是我们的SQL Server是运行在Wind ...
- sql查询磁盘空间并发预警邮件
检测磁盘空间,如果低于设置的预警值则发出一封预警邮件,这样的事情可以用SQL server的作业可以做,关键SQL语句如下例子所示: DECLARE @TableText NVARCHAR(MAX)= ...
- Linux下监控磁盘空间的四个命令
无论是运行简单的Linux桌面还是大型Linux服务器,都需要了解可供应用程序使用的空间,并跟踪系统的磁盘使用情况.下面介绍四个核心命令行命令来管理Linux系统上的介质环境. 一.mount命令 m ...
- MS SQL 监控错误日志的告警信息
SQL Server的错误消息(Error Message)按照消息的严重级别一共划分25个等级,级别越高,表示严重性也越高.但是如果你统计sys.messages,你会发现,实际上只有16(SQL ...
- [Linux监控]磁盘空间大小
echo 192.168.10.69>>ip.list ------------------------------------------- #!/bin/bash #注意if和[]之间 ...
- Linux磁盘空间监控告警
Linux系统中需要监控磁盘各分区的使用情况,避免由于各种突发情况,造成磁盘空间被消耗殆尽的情况,例如某个分区被Oracle的归档日志耗尽,导致后续的日志文件无法归档,这时ORACLE数据库就会出现错 ...
- (转)Linux磁盘空间监控告警 && Linux磁盘管理
Linux磁盘空间监控告警 http://blog.csdn.net/github_39069288/article/details/73478784-----------Linux磁盘管理 原文:h ...
- SQL Server 死锁的告警监控
今天这篇文章总结一下如何监控SQL Server的死锁,其实以前写过MS SQL 监控错误日志的告警信息,这篇文章着重介绍如何监控数据库的死锁,当然这篇文章不分析死锁产生的原因.以及如何解决死锁.死锁 ...
随机推荐
- jsp数据
---恢复内容开始--- JSP 是什么 JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结 ...
- python Database Poll for SQL SERVER
python连接SQL SERVER数据库: Python编程中可以使用SQL SERVER 进行数据库的连接及诸如查询/插入/更新等操作,但是每次连接SQL SERVER 数据库请求时,都是独立的去 ...
- 【Java】synchronized与lock的区别
从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了 ...
- Memory Map
计算机最重要的功能单元之一是Memory.Memory是众多存储单元的集合,为了使CPU准确地找到存储有某个信息的存储单元,必须为这些单元分配一个相互区别的“身份证号”,这个“身份证号”就是地址编码. ...
- JSR-303校验类型
空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null, 无法查检长度为0的字符串 @NotBlank 检查约束字符串是不是Null还有被Trim的长 ...
- Friday for Oldboy
计算机的硬件介绍 1. CPU的工作流程:取指令->解码->执行 . 程序状态字寄存器(Program Status Word,PSW)中有一个二进制位控制这两种模式. 内核态:当cp ...
- <魔域>按键精灵脚本
用了三天时间才写完,实现了通过图片识别读取坐标数值,自动寻路等简单功能. 主要的难点在于游戏中的坐标系,和电脑屏幕的坐标系存在三维旋转关系,难以换算. //全局变量:第一个数左上右下坐标 Global ...
- git客户端安装后,访问不到gitsever解决办法
1,运行 git Bash 客户端 $ cd ~/.ssh 如果没有此目录则创建一个 $ mkdir ~/.ssh 2,在.ssh目录下 $ ssh-keygen -t rsa -C "你的 ...
- [51nod1743]雪之国度
雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路. 雪之女王赋予了每一座城市不同的能量,其中第i座城市被赋予 ...
- hdu_1010_Tempter of the Bone_dfs
题意:给出一个地图,起点和终点,四通路(上下左右),问在一定的时间内可以走出这个地图吗 题解:首先这个题意一定要好好读,很容易读错题,理解成最短路径小于给定时间就可以出去,其实是不可以的,必须要在给定 ...