DBCC SHRINKFILE 実行時のメッセージ

本間 崇
SQL Server Support Escalation Engineer

現象

トランザクションログファイルを圧縮するために、DBCC SHRINKFILE コマンドを実行した場合に、メッセージと共に圧縮が行えないことがあります。

例えば、以下のようなメッセージで圧縮が行えないような状況です。

DBCC の実行が完了しました。DBCC がエラー メッセージを出力した場合は、システム管理者に相談してください。
ログ ファイル 2 (shrinktest_log) を圧縮できません。要求されたサイズ (448512 KB) が最後の論理ログ ファイルの開始位置よりも大きくなります。 DbId FileId CurrentSize MinimumSize UsedPages EstimatedPages
------ ----------- ----------- ----------- ----------- --------------
14 2 64000 64000 64000 64000

 

(1 行処理されました)

 

DBCC の実行が完了しました。DBCC がエラー メッセージを出力した場合は、システム管理者に相談してください。

問い合わせ自体は多くいただくものではありませんが、ここでパターンを整理しておこうと思います。

前提知識

このポストで説明する内容を理解するためには、以下の 2 つの技術的なポイントを抑えておく必要があります。

1. トランザクションログファイルは仮想ログファイルで構成されている
2. DBCC SHRINKFILE コマンドは、ファイルの末尾の空いている仮想ログファイルを解放する

まず、1.についてですが、SQL Server の Books Online 等でも説明している通り、SQL Server ではトランザクションログファイルを複数の仮想ログファイル(VLF)という箱に区切って管理しています。イメージとしては、以下のような感じでしょうか。1 つのファイルが 4 つの VLF に区切られている感じです。

image 

もう1つのポイントである、DBCC SRINKFILE コマンドの動作ですが、ファイルの末尾の空いている VLF を解放する、という動作になります。上記の色のついている部分が使用中で、色のついていない部分が空きとすると、ファイル末尾にある VLF4 だけが、空いている状況です。

この状態で、DBCC SHRINKFILE コマンドを実行すると、以下のように VLF4 だけが解放される形となります。VLF3 の空いている部分については解放されません。

image

メッセージについて

さて、それでは DBCC SHRINKFILE 実行時に見ることがあるメッセージについて確認しましょう。

おそらく、作業の際に目にするのは、以下の 3 つだと思います。

1. ログ ファイル 2 (xxxxxx) を圧縮できません。ファイルの末尾にある論理ログ ファイルが使用中です。
2. ログ ファイル 2 (xxxxxx) を圧縮できません。要求されたサイズ (448512 KB) が最後の論理ログ ファイルの開始位置よりも大きくなります。
3. ログ ファイル 2 (xxxxxx) を圧縮できません。論理ログ ファイルの総数を 2 未満にはできません。

まず、1 つ目ですが、これは以下のような状態です。ファイル末尾の VLF3 が現在使用中なので、圧縮できないという状態です。VLF1、VLF2 が空いているのでトランザクションログファイルの使用率としては低いですが、圧縮できない状態です。VLF3 が一杯になって、現在のログの位置が VLF1 に移動した後に、もう一度トランザクションログの切捨てが発生してVLF3が空けば、VLF3 が解放できるようになります。

image

2 つ目は、DBCC SHRINKFILE コマンドに、target_size を指定した場合に、発生するメッセージとなります。

わかり易くするため、VLF1 ~ VLF4 まで、それぞれ100MBで、トータル400MBのトランザクションログファイルと仮定します。この状態で、target_size に 300MB より大きい値を設定した場合、末尾の VLF4 の途中を指定したことになるため、解放すべき VLF がなくなります。VLF という単位で行っていることを理解していれば、メッセージの通りということがお分かりいただけると思います。

image

最後の3つ目は、本当に VLF が 2 つしかないので、圧縮できないパターンです。SQL Server では、最小の VLF の数を 2 と定めているため、それ以下には圧縮できません。そのために出力されるメッセージとなります。

image

いずれのパターンも VLF と DBCC SHRINKFILE コマンドの動作を理解いただければ、メッセージの通りの状態であり、致命的な状態ではないというのはご理解いただけるのではないかと思います。

参考

タイトル:トランザクション ログの圧縮
URL:https://msdn.microsoft.com/ja-jp/library/ms178037(v=sql.105).aspx

タイトル:DBCC SHRINKFILE (Transact-SQL)
URL:https://msdn.microsoft.com/ja-jp/library/ms189493(v=sql.105).aspx