7

Our monitoring solution (SCOM) is currently flagging that the tempdb log is running out of space. However we have auto grow set to 1GB chunks for the log and we have 25GB of space left on the drive.

I looked at what the log_reuse_wait_desc was and found it to be ACTIVE_TRANSACTION

I started to wonder if for some reason the log file was filling up and the auto grow not kicking in, and after some research I found that the log file should still grow even during an ACTIVE_TRANSACTION.

I found an article on a similar issues where the tempdb log ran out of space:

http://sqltimes.wordpress.com/2014/07/05/sql-server-error-messages-the-transaction-log-for-database-tempdb-is-full-due-to-active_transaction/

Here they issued a CHECKPOINT to resolve the issue on tempdb. I know a CHECKPOINT flushes dirty pages to disk, however I do not understand how this would fix the ACTIVE_TRANSACTION problem?

Furthermore I also do not know why we get this alert when there is plenty of space. Is there a situation where a tempdb can fill and auto grow not work for some reason?

  • SCOM monitoring tool check threshold value set for alert in case of disk space, and in your case I guess threshold was set somwhere around 30-25 G it was crossed so alert was fired – Shanky Oct 7 '14 at 17:50
  • @Tom The blog you referred to above is my blog. Hope it was helpful to resolve your issue. – ToC Nov 27 '16 at 0:05
3

As Max mentioned the alert probably fired just prior to the log growing/needing to grow. SCOM collects transaction log free space % although I am not sure at what threshold the alert will fire.

here is a quick example to show you what state tempdb is probably in when you get these alerts but no log file growth.

first create a database, set recovery to full, and back it up

    create database tlogspace
    on(name=tlogspace_dat,
        filename='c:\temp\tlogspace.mdf',
        size=4MB)
    log on (name=tlogspace_log,
        filename='c:\temp\tlogspace.ldf',
        size=1MB);
    go

    alter database tlogspace set recovery full;
    go
    backup database tlogspace to disk='nul';
    go

now switch to that database, create a table, and run DBCC sqlperf(logspace) to check the size oand free space in your log file.

use tlogspace
go

create table data(id int identity(1,1), col varchar(8000))
dbcc sqlperf(logspace)

On my system I have logfile size of 0.9921875 and log space used (%) of 48.4245. Now insert some data into the table and run DBCC sqlperf(logspace) again. On my system 45 rows inserted gave desired results(number of rows inserted may need to be adjusted).

insert into data(col)
select replicate('a',8000)
go 45 --may need to adjust number
dbcc sqlperf(logspace)

This time, the DBCC sqlperf output should show that log size is the same but log space used is just under 100%. In this case, SCOM would probably fire an alert that log space is low. There is no more activity going on to cause the log file to grow and (in this example) no tlog backup to free up used space. tempdb is in simple recovery, so your active transaction probably used up most of the available space and did not release it but there was not enough activity in tempdb to trigger log file growth thus causing the alert fire.

cleanup database when finished

use master
drop database tlogspace
0

This doesn't answer your question, however I thought you might find it helpful to see if there have been any recent log growths:

/*
    Description:    display growth events for all databases on the instance
    by:             Max Vernon
    date:           2014-10-01
*/
DECLARE @Version NVARCHAR(255);
DECLARE @VersionINT INT;
SET @Version = CONVERT(NVARCHAR(255),SERVERPROPERTY('ProductVersion'));
SET @VersionINT = CONVERT(INT, SUBSTRING(@Version,1 ,CHARINDEX('.',@Version)-1));
DECLARE @cmd NVARCHAR(2000);
SET @cmd = '';
IF @VersionINT >= 9
BEGIN
    SET @cmd = 
'
DECLARE @trcfilename VARCHAR(1000);

SELECT @trcfilename = path 
FROM sys.traces 
WHERE is_default = 1;

IF COALESCE(@trcfilename,'''') <> ''''
BEGIN
SELECT
    '''''''' + @@SERVERNAME + '''''','''''' +
     DB_NAME(mf.database_id) + '''''','''''' +
     mf.name + '''''','' +
     CONVERT(VARCHAR(255), a.NumberOfGrowths) + '','' +
     CONVERT(VARCHAR(255), CAST(a.DurationOfGrowthsInSeconds AS decimal(38, 20)))
    FROM
    (
        SELECT
            tt.DatabaseID AS database_id,
            tt.FileName AS LogicalFileName,
            COUNT(*) AS NumberOfGrowths,
            SUM(tt.Duration / (1000 * 1000.0)) AS DurationOfGrowthsInSeconds
            FROM sys.fn_trace_gettable(@trcfilename, default) tt
            WHERE (EventClass IN (92, 93))
            GROUP BY
                tt.DatabaseID,
                tt.FileName
    ) a
    INNER JOIN sys.master_files mf ON
        (mf.database_id = a.database_id) AND
        (mf.name = a.LogicalFileName);
END
ELSE
BEGIN
    SELECT @@SERVERNAME, ''NO TRACE FILE'';
END
';
EXEC sp_executesql @cmd;
END
ELSE
BEGIN
    SELECT @@SERVERNAME, SERVERPROPERTY('ProductVersion');
END

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.