現在、監視ソリューション(SCOM)は、tempdbログの領域が不足していることを通知しています。ただし、ログの自動拡張を1GBチャンクに設定しており、ドライブに25GBの空き領域があります。
log_reuse_wait_desc
を確認したところ、ACTIVE_TRANSACTION
であることがわかりました
なんらかの理由でログファイルがいっぱいになり、自動拡張が開始されないのではないかと疑問に思い始めました。調査の結果、ACTIVE_TRANSACTION
の実行中でもログファイルは引き続き拡張することがわかりました。
Tempdbログの領域が不足する同様の問題に関する記事を見つけました。
ここでは、CHECKPOINT
の問題を解決するためにtempdb
を発行しました。私はCHECKPOINT
がダーティページをディスクにフラッシュすることを知っていますが、これがACTIVE_TRANSACTION
の問題をどのように修正するのかわかりませんか?
さらに、十分なスペースがあるときにこのアラートが表示される理由もわかりません。 tempdb
が満たされ、何らかの理由で自動拡張が機能しない状況はありますか?
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
これはあなたの質問の答えにはなりませんが、最近ログの増加があったかどうかを確認すると役立つと思うかもしれません:
/*
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