Technical Article

Monitor space used for disks, DBs, tables and filegroups

,

I pieced this script together from solutions I found on this and from Brian Knight's excellent book. It creates 3 tables:

- tblDriveLogs. Collects free drivespace info for each drive for each time the script is run.

- tblIndexLogs. Collects info on spaceused for each index and table. Please note that when only af single index exist, TableNm and IndexNm is the same. This is because of the way the info is organized in sysindexes.

- tblFileLogs. Keeps track of the sizes and spaceused in the filegroups and logs for each database.

My idea with this solution was to have way of tracking space and spaceused over time. I wanted to make a Access reporting tool og maybe a nice webpage with some cool stats of the data but haven't got around that yet.

Hope you can use the script. If you find any room for improovement or any stupidities please let me know. If you think it's great please let me also know πŸ˜‰ Thanks.

/*
usp_MySpaceUsed
Tracks/Logs spaceusage on your disk, file/filegroups og tables/indexes

This script creates a database REPORTS, the tables and the stored
procedure that you can schedule to run evert day of whatever you
like.

Script by Steen Molberg
Build 100 - Created 10-7-2003
*/
use master
go

create database REPORTS
on 
(
name=dfile1,
filename='D:\data\sql_d\reports_d1.mdf'
)
log on
(
name=lfile1,
filename='L:\sqllog\reports_l1.ldf'
)
go

use REPORTS
go

create table tblDriveLogs
(
[Date] smalldatetime default getdate(),
Drive varchar(1),
MBFree int not null
constraint PK_tblDriveLogs primary key ([Date],Drive)
)
go

create table tblFileLogs
(
[Date] smalldatetime default getdate(),
DbNm varchar(200) not null,
FgNm varchar(200) not null,
FileNm varchar(200) not null,
FilePath varchar(200) not null,
SizePages int not null,
UsedPages int not null
constraint PK_tblFileLogs primary key ([Date],DbNm,FgNm,FileNm) 
)
go

create table tblIndexLogs
(
[Date] smalldatetime default getdate(),
DbNm varchar(200) not null,
FgNm varchar(200) not null,
TableNm varchar(200) not null,
IndexNm varchar(200) not null,
dpages int not null,
reserved int not null,
used int not null
constraint PK_tblIndexLogs primary key ([Date],DbNm,FgNm,TableNm,IndexNm)
)
go

create proc usp_MySpaceUsed
as
set nocount on
declare @LocalErr int
declare @SQL varchar(500)
declare @DbNm sysname	
declare @FileNm sysname
declare @Size int
declare @Groupid int
declare @FilePath varchar(200)
declare @FgNm sysname
declare @IndexNm sysname
declare @TableNm sysname
declare @indid int
declare @dpages int
declare @reserved int
declare @used int

-- Record free space on drives
select @SQL = 
'use Master
insert REPORTS.dbo.tblDriveLogs (Drive,MBFree) exec xp_fixeddrives'
exec (@SQL)

create table #Files
(
[filename] sysname,
[size] int,
[filepath] varchar(200),
groupname varchar(50)
)

create table #Indexes
(
IndexNm sysname,
TableNm sysname,
FgNm sysname,
indid int,
dpages int,
reserved int,
used int
)

-- Interate over Db-names
declare c1 cursor for 
	select [name] from master.dbo.sysdatabases
		where has_dbaccess([name])=1

open c1
fetch c1 into @DbNm
while @@fetch_status=0
begin
	insert #Files exec (
		'use ' + @DbNm + '  ' 
		+ 'select F.[name],F.[size],F.[filename],G.groupname 
		from ' + @DbNm + '.dbo.sysfiles F left join ' + @DbNm + '.dbo.sysfilegroups G
		on F.groupid=G.groupid'
		)

  -- Record filesizes for all dbs on this server
	declare c2 cursor for
		select * from #Files
	open c2
	fetch c2 into @FileNm,@Size,@FilePath,@FgNm
	while @@fetch_status=0
	begin
		select @SQL = 
		'use '+ RTRIM(@DbNm)
		+ '  insert REPORTS.dbo.tblFileLogs ([Date],DbNm,FgNm,FileNm,FilePath,SizePages,UsedPages)'
		+ ' values ('
		+ 'getdate(),' 
		+ '''' + RTRIM(@DbNm) + ''',' 
		+ '''' + isnull(@FgNm,'LOG') + ''',' 
		+ '''' + RTRIM(@FileNm) + ''',' 
		+ '''' + RTRIM(@FilePath) + ''',' 
		+ cast(@Size as varchar(10)) + ',CAST(FILEPROPERTY(''' + RTRIM(@FileNm) + ''', ''SpaceUsed'') as int)/8)'
		exec (@SQL)
		fetch c2 into @FileNm,@Size,@FilePath,@FgNm
	end 
	deallocate c2
	delete from #Files

	-- Record Table and Indexes sizes
	insert #Indexes exec (
		'use ' + @DbNm + '  '
		+ ' select I.name,T.name,G.groupname,I.indid,I.dpages,I.reserved,used'
		+ ' from sysindexes I'
		+ ' join sysobjects T on I.id=T.id'
		+ ' join sysfilegroups G on I.groupid=G.groupid'
		+ ' where I.indid in (0,1,255)'
		+ ' union all'
		+ ' select I.name,T.name,G.groupname,I.indid,I.dpages,I.reserved,used'
		+ ' from sysindexes I'
		+ ' join sysobjects T on I.id=T.id'
		+ ' join sysfilegroups G on I.groupid=G.groupid'
		+ ' where I.indid not in (0,1,255)'
		+ ' and I.groupid<>(select X.groupid from sysindexes X where (I.id=X.id) and (X.indid in (0,1)))'
		)
	
	update #Indexes 
	set IndexNm=TableNm
	where indid in (0,1)

	update #Indexes
	set dpages=dpages-S.sumdpages, reserved=reserved-S.sumreserved, used=used-S.sumused
	from #Indexes I
		join 
		(select X.TableNm, sum(X.dpages) sumdpages, sum(X.reserved) sumreserved, sum(X.used) sumused
		from #Indexes X where X.indid not in (0,1,255) group by X.TableNm) S
		on I.TableNm=S.TableNm		
	where I.indid in (0,1)

	insert REPORTS.dbo.tblIndexLogs
		select getdate() as [Date],@DbNm as DbNm, FgNm, TableNm, IndexNm, dpages, reserved, used
		from #Indexes

	delete from #indexes
	-- End log Tables and Indexes sizes

	fetch c1 into @DbNm
end
deallocate c1

drop table #Files
drop table #Indexes
go
-- END OF SCRIPT

Rate

β˜… β˜… β˜… β˜… β˜… β˜… β˜… β˜… β˜… β˜…

1 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

β˜… β˜… β˜… β˜… β˜… β˜… β˜… β˜… β˜… β˜…

1 (1)

You rated this post out of 5. Change rating