Files
DBAdmin/inbox/DataBase/SQLServer/Disk Space Monitoring.sql
T
2026-05-18 06:40:19 +00:00

235 lines
8.0 KiB
Transact-SQL

--==============================================--
/*** SQL SERVER Disk Space Monitoring QUERIES ***/
--==============================================--
-- Supported Versions SQL server 2008 and higher
-------------------------------------------------
----------------------------------------------
/*** 1. Get all Disks Total and Free Size ***/
----------------------------------------------
DECLARE @MOUNTVOL TABLE
( MOUNTVOLResult nVARCHAR(500)
,ExecCommand nVARCHAR(500))
INSERT INTO @MOUNTVOL (MOUNTVOLResult)
EXEC XP_CMDSHELL 'MOUNTVOL'
DELETE @MOUNTVOL WHERE MOUNTVOLResult LIKE '%VOLUME%'
DELETE @MOUNTVOL WHERE MOUNTVOLResult IS NULL
DELETE @MOUNTVOL WHERE MOUNTVOLResult NOT LIKE '%:%'
DELETE @MOUNTVOL WHERE MOUNTVOLResult LIKE '%MOUNTVOL%'
DELETE @MOUNTVOL WHERE MOUNTVOLResult LIKE '%RECYCLE%'
UPDATE @MOUNTVOL SET ExecCommand = 'EXEC XP_CMDSHELL ''FSUTIL VOLUME DISKFREE ' + LTRIM(RTRIM(MOUNTVOLResult)) +''''
DECLARE @DRIVESpace TABLE
( DriveLetter VARCHAR(10)
,DriveInfo VARCHAR(100))
WHILE (SELECT COUNT(*) FROM @MOUNTVOL) <>0
BEGIN
DECLARE @Command nVARCHAR(500), @DriveLetter nVARCHAR(10)
Select @Command = ExecCommand, @DriveLetter= MOUNTVOLResult from @MOUNTVOL
INSERT INTO @DRIVESpace (DriveInfo) Exec sp_executeSQL @Command
UPDATE @DRIVESpace SET DriveLetter=@DriveLetter WHERE DriveLetter IS NULL
DELETE FROM @MOUNTVOL WHERE ExecCommand=@Command
END
DECLARE @FinalResults TABLE
( DriveLetter nVARCHAR(10)
,[TotalDriveSpace(MB)] DECIMAL(18,2)
,[UsedSpaceOnDrive(MB)] AS ([TotalDriveSpace(MB)] - [FreeSpaceOnDrive(MB)])
,[FreeSpaceOnDrive(MB)] DECIMAL(18,2)
,[TotalDriveSpace(GB)] AS CAST(([TotalDriveSpace(MB)]/1024) AS DECIMAL(18,2))
,[UsedSpaceOnDrive(GB)] AS CAST((([TotalDriveSpace(MB)] - [FreeSpaceOnDrive(MB)])/1024) AS DECIMAL(18,2))
,[FreeSpaceOnDrive(GB)] AS CAST(([FreeSpaceOnDrive(MB)]/1024) AS DECIMAL(18,2))
,[%FreeSpace] AS CAST((([FreeSpaceOnDrive(MB)]/[TotalDriveSpace(MB)])*100) AS DECIMAL(18,2)))
INSERT INTO @FinalResults (DriveLetter, [TotalDriveSpace(MB)],[FreeSpaceOnDrive(MB)])
SELECT RTRIM(LTRIM(DriveLetter))
,[TotalDriveSpace(MB)] = SUM(CASE WHEN DriveInfo LIKE 'TOTAL # OF BYTES%' THEN CAST(SUBSTRING(DriveInfo, 32, 48) AS FLOAT) ELSE CAST(0 AS FLOAT) END)/1024/1024
,[FreeSpaceOnDrive(MB)] = SUM(CASE WHEN DriveInfo LIKE 'TOTAL # OF FREE BYTES%' THEN CAST(SUBSTRING(DriveInfo, 32, 48) AS FLOAT) ELSE CAST(0 AS FLOAT) END)/1024/1024
FROM @DRIVESpace
WHERE DriveInfo LIKE 'TOTAL # OF %'
GROUP BY DriveLetter
ORDER BY DriveLetter
SELECT DriveLetter, [TotalDriveSpace(GB)], [TotalDriveSpace(GB)], [%FreeSpace] FROM @FinalResults
-------------------------------------------------
/*** 2. Get databases physical file location ***/
-------------------------------------------------
SELECT DISTINCT Db_name(dovs.database_id)
[Database Name],
mf.physical_name
[Physical File Location],
dovs.logical_volume_name AS
[Logical Name],
dovs.volume_mount_point AS Drive,
CONVERT(INT, dovs.available_bytes / 1048576.0 / 1024) AS
[Free Space (GB)]
FROM sys.master_files mf
CROSS apply sys.Dm_os_volume_stats(mf.database_id, mf.file_id) dovs
ORDER BY [free space (gb)] ASC
----------------------------------------------
/*** 3. List all Databases and its file size ***/
----------------------------------------------
--Data file size
DECLARE @dbsize TABLE (
Dbname sysname,
dbstatus varchar(50),
Recovery_Model varchar(40) DEFAULT ('NA'),
file_Size_MB decimal(30, 2) DEFAULT (0),
Space_Used_MB decimal(30, 2) DEFAULT (0),
Free_Space_MB decimal(30, 2) DEFAULT (0)
)
INSERT INTO @dbsize (Dbname, dbstatus, Recovery_Model, file_Size_MB, Space_Used_MB, Free_Space_MB)
EXEC sp_msforeachdb 'use [?];
select DB_NAME() AS DbName,
CONVERT(varchar(20),DatabasePropertyEx(''?'',''Status'')) ,
CONVERT(varchar(20),DatabasePropertyEx(''?'',''Recovery'')),
sum(size)/128.0 AS File_Size_MB,
sum(CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT))/128.0 as Space_Used_MB,
SUM( size)/128.0 - sum(CAST(FILEPROPERTY(name,''SpaceUsed'') AS INT))/128.0 AS Free_Space_MB
from sys.database_files where type=0 group by type'
-- log file size
DECLARE @logsize TABLE (
Dbname sysname,
Log_File_Size_MB decimal(38, 2) DEFAULT (0),
log_Space_Used_MB decimal(30, 2) DEFAULT (0),
log_Free_Space_MB decimal(30, 2) DEFAULT (0)
)
INSERT INTO @logsize (Dbname, Log_File_Size_MB, log_Space_Used_MB, log_Free_Space_MB)
EXEC sp_msforeachdb 'use [?];
select DB_NAME() AS DbName,
sum(size)/128.0 AS Log_File_Size_MB,
sum(CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT))/128.0 as log_Space_Used_MB,
SUM( size)/128.0 - sum(CAST(FILEPROPERTY(name,''SpaceUsed'') AS INT))/128.0 AS log_Free_Space_MB
from sys.database_files where type=1 group by type'
-- database free size
DECLARE @dbfreesize TABLE (
name sysname,
database_size varchar(50),
Freespace varchar(50) DEFAULT (0.00)
)
INSERT INTO @dbfreesize (name, database_size, Freespace)
EXEC sp_msforeachdb 'use [?];SELECT database_name = db_name()
,database_size = ltrim(str((convert(DECIMAL(15, 2), dbsize) + convert(DECIMAL(15, 2), logsize)) * 8192 / 1048576, 15, 2) + ''MB'')
,''unallocated space'' = ltrim(str((
CASE
WHEN dbsize >= reservedpages
THEN (convert(DECIMAL(15, 2), dbsize) - convert(DECIMAL(15, 2), reservedpages)) * 8192 / 1048576
ELSE 0
END
), 15, 2) + '' MB'')
FROM (
SELECT dbsize = sum(convert(BIGINT, CASE
WHEN type = 0
THEN size
ELSE 0
END))
,logsize = sum(convert(BIGINT, CASE
WHEN type <> 0
THEN size
ELSE 0
END))
FROM sys.database_files
) AS files
,(
SELECT reservedpages = sum(a.total_pages)
,usedpages = sum(a.used_pages)
,pages = sum(CASE
WHEN it.internal_type IN (
202
,204
,211
,212
,213
,214
,215
,216
)
THEN 0
WHEN a.type <> 1
THEN a.used_pages
WHEN p.index_id < 2
THEN a.data_pages
ELSE 0
END)
FROM sys.partitions p
INNER JOIN sys.allocation_units a
ON p.partition_id = a.container_id
LEFT JOIN sys.internal_tables it
ON p.object_id = it.object_id
) AS partitions'
DECLARE @alldbstate TABLE (
dbname sysname,
DBstatus varchar(55),
R_model varchar(30)
)
--select * from sys.master_files
INSERT INTO @alldbstate (dbname, DBstatus, R_model)
SELECT
name,
CONVERT(varchar(20), DATABASEPROPERTYEX(name, 'status')),
recovery_model_desc
FROM sys.databases
--select * from @dbsize
INSERT INTO @dbsize (Dbname, dbstatus, Recovery_Model)
SELECT
dbname,
dbstatus,
R_model
FROM @alldbstate
WHERE DBstatus <> 'online'
INSERT INTO @logsize (Dbname)
SELECT
dbname
FROM @alldbstate
WHERE DBstatus <> 'online'
INSERT INTO @dbfreesize (name)
SELECT
dbname
FROM @alldbstate
WHERE DBstatus <> 'online'
SELECT
d.Dbname AS [Database Name],
d.dbstatus AS [Status],
d.Recovery_Model AS [Recovery Mode],
(file_size_mb + log_file_size_mb) AS [Total DB Size],
fs.Freespace AS [DB Free Space],
d.file_Size_MB AS [MDF Size(MB)],
d.Space_Used_MB AS [MDF Used(MB)],
d.Free_Space_MB AS [MDF Free(MB)],
l.Log_File_Size_MB AS [LDF Size (MB)],
log_Space_Used_MB AS [LDF Used (MB)],
l.log_Free_Space_MB AS [LDF Free (MB)]
FROM @dbsize d
JOIN @logsize l
ON d.Dbname = l.Dbname
JOIN @dbfreesize fs
ON d.Dbname = fs.name
ORDER BY [Database Name] ASC