关键字
SQLServer2005 xp_fixeddrives xp_cmdshell
概述:
目标数据库为sqlserver,在进行etl数据采集过程中,会产生大量的数据与日志,如果磁盘空间不足,将严重影响etl传输效率,本文讲解如何通过xp_fixeddrives+xp_cmdshell获取获取磁盘信息。
当需要维护的sqlserver服务器较多时,可以通过etl将各服务器的磁盘信息抓取到独立的监控服务器上进行分析。
脚本
--==================================
/*
sqlserver2005 启用xp_cmdshell,首先需要在master数据库中执行如下命令:
*/
use master;
-- 启用xp_cmdshell命令:
RECONFIGURE WITH override;
EXEC sp_configure 'show advanced options',1;
RECONFIGURE WITH override;
EXEC sp_configure 'xp_cmdshell',1;
RECONFIGURE WITH override
-- 如果需要禁用xp_cmdshell,执行如下命令:
RECONFIGURE WITH override;
EXEC sp_configure 'xp_cmdshell',0;
RECONFIGURE WITH override;
EXEC sp_configure 'show advanced options',1;
RECONFIGURE WITH override;
/*
在业务库中执行如下命令,创建存储过程:
*/
-- =============================================
-- Author: hury
-- Create date: 2019-09-26 09:28:50
-- Description: 收集磁盘剩余空间信息
-- =============================================
CREATE PROCEDURE [dbo].[usp_get_disk_free_size]
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
--==========================================
--创建相关表
IF OBJECT_ID('server_disk_usage') IS NULL
BEGIN
CREATE TABLE [dbo].[server_disk_usage](
[disk_num] [nvarchar](10) NOT NULL,
[total_size_mb] [bigint] NOT NULL CONSTRAINT [DF_server_disk_usage_total_size_mb] DEFAULT ((0)),
[free_siez_mb] [bigint] NOT NULL CONSTRAINT [DF_server_disk_usage_free_siez_mb] DEFAULT ((0)),
[disk_info] [nvarchar](400) NOT NULL CONSTRAINT [DF_server_disk_usage_disk_info] DEFAULT (''),
[check_time] [datetime] NOT NULL CONSTRAINT [DF_server_disk_usage_check_time] DEFAULT (getdate()),
CONSTRAINT [PK_server_disk_usage] PRIMARY KEY CLUSTERED
(
[disk_num] ASC
)
) ON [PRIMARY]
END
--==========================================
--查看所有数据库使用到的磁盘剩余空间
DECLARE @disk TABLE(
[disk_num] VARCHAR(50),
[free_siez_mb] INT)
INSERT INTO @disk
EXEC xp_fixeddrives
--更新当前磁盘的剩余空间信息
UPDATE M
SET M.[free_siez_mb]=D.[free_siez_mb]
FROM [dbo].[server_disk_usage] AS M
INNER JOIN @disk AS D
ON M.[disk_num]=D.[disk_num]
--插入新增磁盘的剩余空间信息
INSERT INTO [dbo].[server_disk_usage]
(
[disk_num],
[free_siez_mb]
)
SELECT
[disk_num],
[free_siez_mb]
FROM @disk AS D
WHERE NOT EXISTS(
SELECT 1
FROM [dbo].[server_disk_usage] AS M
WHERE M.[disk_num]=D.[disk_num] )
END
GO
-- =============================================
-- Author: hury
-- Create date: 2019-09-26 09:28:50
-- Description: 收集磁盘总空间信息
-- =============================================
CREATE PROCEDURE [dbo].[usp_get_disk_total_size]
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
IF NOT EXISTS(SELECT * FROM [dbo].[server_disk_usage]
WHERE [total_size_mb] = 0)
BEGIN
RETURN;
END
--========================================
--创建临时表用来存放每个盘符的数据
CREATE TABLE #tempDisks
(
ID INT IDENTITY(1,1),
DiskSpace NVARCHAR(200)
)
--============================================
--将需要检查的磁盘放入临时表#checkDisks
SELECT
ROW_NUMBER()OVER(ORDER BY [disk_num]) AS RID,
[disk_num]
INTO #checkDisks
FROM [dbo].[server_disk_usage]
WHERE [total_size_mb] = 0;
--============================================
--循环临时表#checkDisks检查每个磁盘的总量
DECLARE @disk_num NVARCHAR(20)
DECLARE @total_size_mb INT
DECLARE @sql NVARCHAR(200)
DECLARE @max INT
DECLARE @min INT
SELECT @max=MAX(RID),@min=MIN(RID) FROM #checkDisks
WHILE(@min<=@max)
BEGIN
SELECT @disk_num=[disk_num]
FROM #checkDisks WHERE RID=@min
SET @sql = N'EXEC sys.xp_cmdshell ''fsutil volume diskfree '+@disk_num+':'+''''
PRINT @sql
INSERT INTO #tempDisks
EXEC sys.sp_executesql @sql
SELECT @total_size_mb=CAST((RIGHT(DiskSpace,LEN(DiskSpace)
-CHARINDEX(': ',DiskSpace)-1)) AS BIGINT)/1024/1024
FROM #tempDisks WHERE id = 2
-- SELECT @total_size_mb,@disk_num
UPDATE [dbo].[server_disk_usage]
SET [total_size_mb]=@total_size_mb
WHERE [disk_num]=@disk_num
--SELECT * FROM #tempDisks
TRUNCATE TABLE #tempDisks
SET @min=@min+1
END
END
GO
-- =============================================
-- Author: hury
-- Create date: 2019-09-26 09:28:50
-- Description: 收集磁盘总空间信息
-- =============================================
CREATE PROCEDURE [dbo].[usp_get_disk_usage]
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
EXEC [dbo].[usp_get_disk_free_size]
EXEC [dbo].[usp_get_disk_total_size]
END
GO
--==================================
/*
执行收集磁盘总空间信息
*/
EXEC [dbo].[usp_get_disk_usage]
/*
获取磁盘容量信息
*/
SELECT [disk_num] AS name
, CAST([total_size_mb]/1024.0 AS NUMERIC(18,2)) AS max_size_g
, CAST(([total_size_mb]-[free_siez_mb])/1024.0 AS NUMERIC(18,2)) AS Used_Space_GB
, CAST([free_siez_mb]/1024.0 AS NUMERIC(18,2)) AS free_size_g
, CAST([free_siez_mb]*100/[total_size_mb] AS NUMERIC(18,2)) AS Free_Space_Percent
, [check_time]
FROM [dbo].[server_disk_usage]
执行结果:
–END–