SQL Server – Space – Data And Log File Growth Auto-Grow History TSQL

I apologize for the lull in my blogging. After most of my blog posts were completely ripped off by a Chinese website (full copy/paste or web-crawl and replace my name type plagiarism) a switch just flipped in my brain. I am trying again after submitting complaints with Google (Thanks to Brent Ozar for the guidance) and removing them from the top of the search results for now although they continue to operate fine.

With is really simple post today, I wanted to show you how to see the space growth history in SQL Server. Please check out my related post on how to do space analysis with PowerBI and PowerShell.

How to get auto-grow events history

There is the easy UI method and the custom query method. Basically, we want something like this produced by the “Method 1” report below.

DiskUsageAndAutoGrowEvents.jpg

Method 1 – Disk Usage Report:

The easiest way is to use the built-in SSMS report.

  • Right click on the database
  • Report
  • Disk usage
  • Expand “Data/Log Files Autogrow Shrink Events”

Method 2 – TSQL Query:

This is a method that you can use if you want programmatic data capture. I just did a trace to get the SQL from what SSMS issued under the covers (ripped off from MS! ;-)).

Query 1- Overall space summary (shown at the top of the report)

BEGIN try
    DECLARE @dbsize BIGINT
    DECLARE @logsize BIGINT
    DECLARE @database_size_mb FLOAT
    DECLARE @unallocated_space_mb FLOAT
    DECLARE @reserved_mb FLOAT
    DECLARE @data_mb FLOAT
    DECLARE @log_size_mb FLOAT
    DECLARE @index_mb FLOAT
    DECLARE @unused_mb FLOAT
    DECLARE @reservedpages BIGINT
    DECLARE @pages BIGINT
    DECLARE @usedpages BIGINT 

    SELECT @dbsize = Sum(CONVERT(BIGINT, CASE
                                           WHEN status & 64 = 0 THEN size
                                           ELSE 0
                                         END)),
           @logsize = Sum(CONVERT(BIGINT, CASE
                                            WHEN status & 64 != 0 THEN size
                                            ELSE 0
                                          END))
    FROM   dbo.sysfiles 

    SELECT @reservedpages = Sum(a.total_pages),
           @usedpages = Sum(a.used_pages),
           @pages = Sum(CASE
                          WHEN it.internal_type IN ( 202, 204 ) 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
           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

    SELECT @reserved_mb = @reservedpages * 8192 / 1048576.0 

    SELECT @data_mb = @pages * 8192 / 1048576.0 

    SELECT @log_size_mb = CONVERT(DEC(19, 2), @logsize) * 8192 / 1048576.0 

    SELECT @index_mb = ( @usedpages - @pages ) * 8192 / 1048576.0 

    SELECT @unused_mb = ( @reservedpages - @usedpages ) * 8192 / 1048576.0 

    SELECT @database_size_mb                        AS 'database_size_mb',
           @reserved_mb                             AS 'reserved_mb',
           @unallocated_space_mb                    AS 'unallocated_space_mb',
           ( @reserved_mb + @unallocated_space_mb ) AS 'data_size',
           @log_size_mb                             AS 'transaction_log_size',
           Cast(@unallocated_space_mb * 100.0 / (
                @reserved_mb + @unallocated_space_mb ) AS
                DECIMAL(10, 2))                     AS 'unallocated',
           Cast(@reserved_mb * 100 / ( @reserved_mb + @unallocated_space_mb ) AS
                DECIMAL(10, 2))                     AS 'reserved',
           Cast(@data_mb * 100 / ( @reserved_mb + @unallocated_space_mb ) AS
                DECIMAL
                (10, 2)
           )                                        AS 'data',
           Cast(@index_mb * 100 / ( @reserved_mb + @unallocated_space_mb ) AS
                DECIMAL(10, 2))                     AS 'index_1',
           Cast(@unused_mb * 100 / ( @reserved_mb + @unallocated_space_mb ) AS
                DECIMAL(10, 2))                     AS 'unused';
END try 

BEGIN catch
    SELECT 1                AS database_size_mb,
           Error_number()   AS reserved_mb,
           Error_severity() AS unallocated_space_mb,
           Error_state()    AS data_size,
           1                AS transaction_log_size,
           Error_message()  AS unallocated,
           -100             AS reserved,
           1                AS data,
           1                AS index_1,
           1                AS unused
END catch

Query 2 – Auto-growth events shown at the bottom of the image

As you can see the data comes from reading the default trace file using the function fn_trace_gettable and filtering it for EventClasses between 92 and 95 that correspond to auto-growth!


begin try
	if (select convert(int,value_in_use) from sys.configurations where name = 'default trace enabled' ) = 1
	begin
		declare @curr_tracefilename varchar(500) ;
		declare @base_tracefilename varchar(500) ;
		declare @indx int ;

		select @curr_tracefilename = path from sys.traces where is_default = 1 ;
		set @curr_tracefilename = reverse(@curr_tracefilename);
		select @indx  = patindex('%\%', @curr_tracefilename) ;
		set @curr_tracefilename = reverse(@curr_tracefilename) ;
		set @base_tracefilename = left( @curr_tracefilename,len(@curr_tracefilename) - @indx) + '\log.trc' ;

		select  (dense_rank() over (order by StartTime desc))%2 as l1
		,       convert(int, EventClass) as EventClass
		,       DatabaseName
		,       Filename
		,       (Duration/1000) as Duration
		,       StartTime
		,       EndTime
		,       (IntegerData*8.0/1024) as ChangeInSize
		from ::fn_trace_gettable( @base_tracefilename, default )
		left outer join sys.databases as d on (d.name = DB_NAME())
		where EventClass >=  92      and EventClass <=  95        and ServerName = @@servername   and DatabaseName = db_name()  and (d.create_date < EndTime)
		order by StartTime desc ;
	end
	else
		select -1 as l1, 0 as EventClass, 0 DatabaseName, 0 as Filename, 0 as Duration, 0 as StartTime, 0 as EndTime,0 as ChangeInSize
end try
begin catch
	select -100 as l1
	,       ERROR_NUMBER() as EventClass
	,       ERROR_SEVERITY() DatabaseName
	,       ERROR_STATE() as Filename
	,       ERROR_MESSAGE() as Duration
	,       1 as StartTime, 1 as EndTime,1 as ChangeInSize
end catch

Below is a screenshot of the TSQL query results. Event class 93 corresponds to Log file auto-growth and 92 for Data file.AutoGrowEventsTSQL.jpg

I know that was a really quick post but I hope that you find it useful.

Advertisement

6 thoughts on “SQL Server – Space – Data And Log File Growth Auto-Grow History TSQL

  1. Below is the error Message when I execute Space Summery
    Msg 4104, Level 16, State 1, Line 20
    The multi-part identifier “a.total_pages” could not be bound.
    Msg 4104, Level 16, State 1, Line 21
    The multi-part identifier “a.used_pages” could not be bound.
    Msg 4104, Level 16, State 1, Line 23
    The multi-part identifier “it.internal_type” could not be bound.
    Msg 4104, Level 16, State 1, Line 23
    The multi-part identifier “it.internal_type” could not be bound.
    Msg 4104, Level 16, State 1, Line 24
    The multi-part identifier “a.type” could not be bound.
    Msg 4104, Level 16, State 1, Line 25
    The multi-part identifier “p.index_id” could not be bound.
    Msg 4104, Level 16, State 1, Line 24
    The multi-part identifier “a.used_pages” could not be bound.

      1. Hi Jana,

        I Tried in SQL 2012,14,16,17 versions, getting same error when I execute query 1.

      2. Hi Jagadeesh, I apologize for missing a part of the SQL and thank you for bringing it to my attention. I have updated it. Can you please try it again?

    1. It kept dropping part of my script. I have updated it manually and now it seems to be okay. There should have been some special characters in there that WordPress did not like. Sorry again.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s