How can I find out when a database has auto-grown? I'd like to know how often a certain database has automatically grown without any DBA intervention and, if possible, which files have auto-grown and to what size. With this information, I could more easily decide whether to let a database auto-grow and how much to let it grow.

Many DBAs ask this question. SQL Server 2000 doesn't have a built-in function for retrieving this information. However, you can determine this information fairly easily by setting up a baseline of file size per database and remembering to re-baseline after any manual growth operation. The following command will give you the total number of 8K data pages in a database:

SELECT GETDATE(), SUM(size)
  FROM[dbname].dbo.sysfiles

WHERE status & 0x40 <> 0x40 — /* Use status flag to exclude log files.*/

If you save the results of this query to a baseline table, then periodically compare these results with the current values, you'll see the growth. If you remember to re-baseline after each manual growth operation, you should see only autogrow operations. To track individual file growth, you can modify the query to look something like this:

SELECT GETDATE(),name,size
  FROM pessimistic.dbo.sysfiles
  WHERE status & 0x40 <> 0x40

And if you track growth over time (i.e., maintain multiple rows in your baseline table, and perhaps build an Analysis Services cube to track the data), you can capture the velocity of growth. In SQL Server 2005, you'll be able to build logic to capture the Data_File_Auto_Grow and Audit_Database_* (to be defined) trace events as notifications and to process the notifications, maybe by adding the new size to the baseline table.

End of Article




You must log on before posting a comment.

If you don't have a username & password, please register now.

Reader Comments

I've thought about using SQL Server 2000's Profiler to script a trace to track the relevant events. These events occur sufficiently infrequently that overhead ought to be acceptable. We could use sp_ProcOption to make exec the script on re-start. We'd have to create some mechanism to make sure to create a different file name on re-start (say, using GetDate()). Better yet would be to write the results directly to table; however, I'd have to noodle this a bit before knowing whether that would be simple to automate.

AspiringGeek

Article Rating 4 out of 5

Here's the version of the script that will enumerate all databases and display their sizes:

-- script to enumerate databases -- sedlitz.ca

set nocount on set use master

DECLARE cur CURSOR FOR SELECT CATALOG_NAME FROM INFORMATION_SCHEMA.SCHEMATA OPEN cur DECLARE @dbname sysname

print @@servername + ': ' + convert(varchar(10),getdate(),101) print ' '

FETCH NEXT FROM cur INTO @dbname WHILE (@@FETCH_STATUS <> -1) BEGIN IF (@@FETCH_STATUS <> -2) BEGIN SELECT @dbname = RTRIM(@dbname) -- Do something for each DB print 'DATABASE: ' + @dbname print ' ' -- size is reported in 8K page units exec ('select size*8/1024 as "Size (MB)", maxsize*8/1024 as "Maxsize (MB)", growth, name, filename from ' + @dbname + '.dbo.sysfiles') END FETCH NEXT FROM cur INTO @dbname END CLOSE cur DEALLOCATE cur

Anonymous User

Article Rating 3 out of 5

Here is little better version of dbSize for all dbs:

if object_id('tempdb.dbo.dbSize') is not null drop table tempdb.dbo.dbSize go

create table tempdb.dbo.dbSize ( dbName sysname, dataMB numeric(10,2), logMB numeric(10,2), dbMB numeric(10,2) ) go

EXEC sp_MSforeachdb 'INSERT tempdb.dbo.dbSize ( dbName, dataMB, logMB ) SELECT dbName = '?', dataMB = ( SELECT Cast (Round((SUM(size)*8.0)/1024.0,2) AS numeric(10,2)) FROM [?].dbo.sysfiles WHERE status & 0x40 <> 0x40 ), logMB = ( SELECT Cast (Round((SUM(size)*8.0)/1024.0,2) AS numeric(10,2)) FROM [?].dbo.sysfiles WHERE status & 0x40 = 0x40 ) '

update tempdb.dbo.dbSize set dbMB = dataMB + logMB go

select dbName=Cast ( dbName AS varchar(30)), dataMB, logMB, dbMB from tempdb.dbo.dbSize -- where dbMB > 1000 order by dbMB desc, dbName go

Anonymous User

Article Rating 5 out of 5