web-dev-qa-db-ja.com

TempDBログスペースとACTIVE_TRANSACTION

現在、監視ソリューション(SCOM)は、tempdbログの領域が不足していることを通知しています。ただし、ログの自動拡張を1GBチャンクに設定しており、ドライブに25GBの空き領域があります。

log_reuse_wait_descを確認したところ、ACTIVE_TRANSACTIONであることがわかりました

なんらかの理由でログファイルがいっぱいになり、自動拡張が開始されないのではないかと疑問に思い始めました。調査の結果、ACTIVE_TRANSACTIONの実行中でもログファイルは引き続き拡張することがわかりました。

Tempdbログの領域が不足する同様の問題に関する記事を見つけました。

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

ここでは、CHECKPOINTの問題を解決するためにtempdbを発行しました。私はCHECKPOINTがダーティページをディスクにフラッシュすることを知っていますが、これがACTIVE_TRANSACTIONの問題をどのように修正するのかわかりませんか?

さらに、十分なスペースがあるときにこのアラートが表示される理由もわかりません。 tempdbが満たされ、何らかの理由で自動拡張が機能しない状況はありますか?

7
Tom

Maxが言及したように、ログが成長する/成長する必要がある直前にアラートが発生した可能性があります。 SCOMはトランザクションログの空き領域%を収集しますが、アラートが発生するしきい値はわかりません。

以下は、これらのアラートを受け取ったがログファイルの増加がない場合にtempdbがどのような状態にあるかを示す簡単な例です。

最初にデータベースを作成し、リカバリをフルに設定して、バックアップします

    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

次に、そのデータベースに切り替え、テーブルを作成し、 DBCC sqlperf(logspace) を実行して、ログファイルのサイズと空き領域を確認します。

use tlogspace
go

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

私のシステムでは、0.9921875のログファイルサイズと48.4245の使用済みログ領域(%)があります。次に、テーブルにデータを挿入し、DBCC sqlperf(logspace)を再度実行します。私のシステムでは、挿入された45行で望ましい結果が得られました(挿入された行の数を調整する必要がある場合があります)。

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

今回は、DBCC sqlperfの出力に、ログサイズは同じであるが、使用されるログ領域が100%未満であることが示されます。この場合、SCOMはおそらくログスペースが少ないというアラートを発します。ログファイルが大きくなる原因となるアクティビティはこれ以上なく、(この例では)使用済みスペースを解放するtlogバックアップはありません。 tempdbは単純な回復状態にあるため、アクティブなトランザクションが使用可能な領域のほとんどを使い果たして解放しなかった可能性がありますが、tempdbに十分なアクティビティがなかったため、ログファイルの増大を引き起こし、アラートが発生しました。

終了時にデータベースをクリーンアップ

use master
drop database tlogspace
3
Bob Klimes

これはあなたの質問の答えにはなりませんが、最近ログの増加があったかどうかを確認すると役立つと思うかもしれません:

/*
    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
0
Max Vernon