DBCC SHRINKFILE (Transact-SQL)

現在のデータベース用の、指定したデータ ファイルまたはログ ファイルのサイズを圧縮します。または、指定したファイルのデータを同じファイル グループ内の別のファイルに移動してファイルを空にし、ファイルをデータベースから削除できるようにします。ファイルを圧縮すると、ファイルの作成時に指定したサイズよりも小さなサイズにできます。実行すると、最小ファイル サイズは新しい値にリセットされます。

トピック リンク アイコンTransact-SQL 構文表記規則

構文

DBCC SHRINKFILE 
(
    { file_name | file_id } 
    { [ , EMPTYFILE ] 
    | [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]
    }
)
[ WITH NO_INFOMSGS ]

引数

  • file_name
    圧縮するファイルの論理名を指定します。

  • file_id
    圧縮するファイルの識別 (ID) 番号を指定します。ファイル ID を取得するには、システム関数 FILE_IDEX を使用するか、現在のデータベースで sys.database_files カタログ ビューに対してクエリを実行します。

  • target_size
    ファイルのサイズを MB 単位で表す整数値を指定します。この値を指定しない場合、DBCC SHRINKFILE では既定のファイル サイズまでサイズが圧縮されます。既定のサイズは、ファイル作成時に指定されたサイズです。

    注意

    DBCC SHRINKFILE target_size を使用して、空のファイルの既定のサイズを小さくすることができます。たとえば、5 MB のファイルを作成してから、ファイルがまだ空のうちに 3 MB に圧縮した場合、既定のファイル サイズは 3 MB に設定されます。これは、データが含まれたことがない空のファイルにのみ適用されます。

    target_size を指定した場合、DBCC SHRINKFILE では、指定されたサイズまでファイルの圧縮が試行されます。解放されたファイル内の使用ページは、保持されるファイル部分の空き領域に移されます。たとえば、10 MB のデータ ファイルの場合、target_size を 8 にして DBCC SHRINKFILE 操作を実行すると、ファイルの末尾 2 MB にあるすべての使用ページがファイルの先頭 8 MB にある未割り当てのページに再割り当てされます。DBCC SHRINKFILE では、ファイル内に格納されているデータのサイズ以下に、ファイルを圧縮することはできません。たとえば、10 MB のデータ ファイルのうち 7 MB が使用されている場合、target_size を 6 にして DBCC SHRINKFILE ステートメントを実行しても、ファイルは 7 MB にまでしか圧縮できず、6 MB にはなりません。

  • EMPTYFILE
    指定したファイルから、同じファイル グループ内の他のファイルにすべてのデータを移動します。データベース エンジンではデータを空のファイルに配置できなくなったので、ファイルを削除するには、ALTER DATABASE ステートメントを使用します。

  • NOTRUNCATE
    データ ファイル末尾の割り当て済みページをファイル先頭の未割り当てページに移動します。必要に応じて target_percent を指定することもできます。ファイル末尾の空き領域はオペレーティング システムに返されず、ファイルの物理サイズは変わりません。したがって、NOTRUNCATE を指定した場合は、ファイルが圧縮されていないように見えます。

    NOTRUNCATE はデータ ファイルにのみ適用され、ログ ファイルは影響を受けません。

  • TRUNCATEONLY
    ファイル末尾のすべての空き領域をオペレーティング システムに渡します。ただし、ファイル内でのページの移動は行われません。データ ファイルは、最後に割り当てられたエクステントを限度として圧縮されます。

    target_size は TRUNCATEONLY と共に指定した場合、無視されます。

    TRUNCATEONLY はデータ ファイルにのみ適用されます。

  • WITH NO_INFOMSGS
    すべての情報メッセージを表示しないようにします。

結果セット

次の表では、結果セットの列について説明します。

列名

説明

DbId

データベース エンジンで圧縮が試行されたファイルのデータベース識別番号。

FileId

データベース エンジンで圧縮が試行されたファイルのファイル識別番号。

CurrentSize

ファイルが現在占有する 8 KB ページの数。

MinimumSize

ファイルが占有できる 8 KB ページの最小数。この値は、ファイルの最小サイズまたは最初に作成されたサイズと一致します。

UsedPages

ファイルが現在使用している 8 KB ページの数。

EstimatedPages

データベース エンジンで推定されるファイル圧縮後の 8 KB ページの数。

説明

DBCC SHRINKFILE は現在のデータベース内のファイルに適用されます。現在のデータベースを変更する方法の詳細については、「USE (Transact-SQL)」を参照してください。

DBCC SHRINKFILE 操作は、プロセスのどの時点でも中断でき、中断時に完了していた作業は保持されます。

DBCC SHRINKFILE 操作が失敗すると、エラーが発生します。

圧縮されるデータベースは、シングル ユーザー モードになっている必要はありません。ファイルの圧縮中も、他のユーザーはそのデータベースで作業することができます。システム データベースを圧縮するために、SQL Server インスタンスをシングル ユーザー モードで実行する必要はありません。

ログ ファイルの圧縮

ログ ファイルの場合、データベース エンジンでは target_size を使用してログ全体の目標サイズが計算されます。つまり、target_size は圧縮処理後のログ内の空き領域サイズになります。計算の後、ログ全体の目標サイズは各ログ ファイルの目標サイズに変換されます。DBCC SHRINKFILE では、各物理ログ ファイルの目標サイズへの圧縮がすぐに試行されます。しかし、目標サイズを超える仮想ログ内に論理ログの一部がある場合は、データベース エンジンによってできるだけ多くの領域が解放され、情報メッセージが出力されます。このメッセージには、ファイルの末尾で仮想ログから論理ログを移動するために行う必要のある操作が説明されています。この操作を実行した後、DBCC SHRINKFILE を使って、残りの領域を解放できます。詳細については、「トランザクション ログの圧縮」を参照してください。

ログ ファイルは仮想ログ ファイルの境界を越えて圧縮できないため、ログ ファイルを仮想ログ ファイルのサイズより小さく圧縮することはできません。これはログ ファイルが使用されていない場合でも同じです。仮想ログ ファイルのサイズは、ログ ファイルの作成時または拡張時に、データベース エンジンにより動的に選択されます。仮想ログ ファイルの詳細については、「トランザクション ログの物理アーキテクチャ」を参照してください。

ベスト プラクティス

ファイルを圧縮する場合は次のことを考慮してください。

  • 圧縮操作は、テーブルの切り捨てやテーブルの削除操作など、大きな未使用領域を生成する操作の後に実行すると最も効果的です。

  • ほとんどのデータベースでは、毎日の定期的操作で使用するための空き領域が必要です。データベースを何度圧縮しても、データベースのサイズが大きくなってしまう場合は、通常の操作にそれだけの領域が必要であることを示しています。このような場合、繰り返しデータベースを圧縮することは無意味です。

  • 圧縮操作では、データベース内のインデックスの断片化状態は保持されず、一般に、断片化の程度が大きくなります。この理由からも、データベースを繰り返し圧縮することはお勧めできません。

トラブルシューティング

ここでは、DBCC SHRINKFILE コマンドを実行する場合に発生する可能性のある問題を診断し修正する方法について説明します。

ファイルが圧縮されない

圧縮操作がエラーなしで実行されても、ファイルのサイズが変わらないように見える場合は、次のいずれかの操作を実行して、ファイルに削除可能な十分な空き領域があるかどうかを確認してください。

  • 次のクエリを実行します。

    SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
    FROM sys.database_files;
    
  • DBCC SQLPERF コマンドを実行し、トランザクション ログで使用されている領域を返します。

使用できる空き領域が不十分な場合、圧縮操作ではこれ以上ファイル サイズを減らすことはできません。

通常、圧縮されていないように見えるのはログ ファイルです。これは多くの場合、ログ ファイルが切り捨てられなかった結果として起こります。ログを切り捨てるには、データベース復旧モデルを SIMPLE に設定するか、ログをバックアップして再度 DBCC SHRINKFILE 操作を実行します。詳細については、「トランザクション ログの切り捨て」および「トランザクション ログの圧縮」を参照してください。

圧縮操作がブロックされる

トランザクションが行のバージョン管理に基づく分離レベルで実行されている場合、圧縮操作がブロックされることがあります。たとえば、DBCC SHRINK DATABASE 操作を実行するときに、行のバージョン管理に基づく分離レベルでの大規模な削除操作が進行中の場合、圧縮操作は削除処理が完了してから実行され、ファイルが圧縮されます。この場合、DBCC SHRINKFILE および DBCC SHRINKDATABASE 操作によって、最初の 1 時間は 5 分ごと、それ以降は 1 時間ごとに、情報メッセージ (SHRINKDATABASE は 5202、SHRINKFILE は 5203) が SQL Server エラー ログに出力されます。たとえば、エラー ログに次のエラー メッセージが含まれているとします。

DBCC SHRINKFILE for file ID 1 is waiting for the snapshot 
transaction with timestamp 15 and other snapshot transactions linked to 
timestamp 15 or with timestamps older than 109 to finish.

これは、スナップショット トランザクションに、圧縮操作により完了された最後のトランザクションである 109 より古いタイムスタンプがあり、それによって圧縮操作がブロックされていることを意味しています。また、sys.dm_tran_active_snapshot_database_transactions 動的管理ビューの transaction_sequence_num 列または first_snapshot_sequence_num 列に、値 15 が含まれることも示しています。このビューの transaction_sequence_num 列または first_snapshot_sequence_num 列のいずれかに、圧縮操作により完了した最後のトランザクション (109) より低い番号が含まれている場合は、それらのトランザクションが終了するまで圧縮操作は待機状態となります。

この問題を解決するには、次のいずれかの作業を実行します。

  • 圧縮操作をブロックしているトランザクションを終了します。

  • 圧縮操作を終了します。圧縮操作を終了した場合、完了済みの作業は保持されます。

  • 何もせず、ブロックしているトランザクションが完了するまで圧縮操作を待機状態にしておきます。

SQL Server のエラー ログの詳細については、「SQL Server エラー ログの表示」を参照してください。

権限

sysadmin 固定サーバー ロールまたは db_owner 固定データベース ロールのメンバーシップが必要です。

A. 指定した目標サイズにデータ ファイルを圧縮する

次の例では、UserDB ユーザー データベース内の DataFile1 というデータ ファイルのサイズを 7 MB に圧縮します。

USE UserDB;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO

B. 指定した目標サイズにログ ファイルを圧縮する

次の例では、AdventureWorks2008R2 データベース内のログ ファイルを 1 MB に圧縮します。DBCC SHRINKFILE コマンドを使用してファイルを圧縮するため、まずデータベース復旧モデルを SIMPLE に設定してファイルを切り捨てます。

USE AdventureWorks2008R2;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2008R2_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY FULL;
GO

C. データ ファイルを切り捨てる

次の例では、AdventureWorks2008R2 データベース内のプライマリ データ ファイルを切り捨てます。sys.database_files カタログ ビューに対してクエリを実行し、データ ファイルの file_id を取得します。

USE AdventureWorks2008R2;
GO
SELECT file_id, name
FROM sys.database_files;
GO
DBCC SHRINKFILE (1, TRUNCATEONLY);

D. ファイルを空にする

次の例では、データベースから削除できるようファイルを空にします。この例では、最初にデータ ファイルを作成します。ファイルにはデータが含まれていることが前提となっています。

USE AdventureWorks2008R2;
GO
-- Create a data file and assume it contains data.
ALTER DATABASE AdventureWorks2008R2 
ADD FILE (
    NAME = Test1data,
    FILENAME = 'C:\t1data.ndf',
    SIZE = 5MB
    );
GO
-- Empty the data file.
DBCC SHRINKFILE (Test1data, EMPTYFILE);
GO
-- Remove the data file from the database.
ALTER DATABASE AdventureWorks2008R2
REMOVE FILE Test1data;
GO