DBCC シュリンクデータベース (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsMicrosoft Fabric SQL Database

指定したデータベース内のデータ ファイルとログ ファイルのサイズを圧縮します。

縮小手術を定期的なメンテナンスと考えないでください。 定期的な定期的なビジネス操作によって拡大するデータ ファイルとログ ファイルでは、縮小操作は必要ありません。

Transact-SQL 構文表記規則

構文

SQL Server の構文:

DBCC SHRINKDATABASE
( database_name | database_id | 0
     [ , target_percent ]
     [ , { NOTRUNCATE | TRUNCATEONLY } ]
)
[ WITH
    {
         [ WAIT_AT_LOW_PRIORITY
            [ (
                  <wait_at_low_priority_option_list>
             ) ]
         ]
         [ , NO_INFOMSGS ]
    }
]

<wait_at_low_priority_option_list> ::=
    <wait_at_low_priority_option>
    | <wait_at_low_priority_option_list>
      , <wait_at_low_priority_option>

<wait_at_low_priority_option> ::=
  ABORT_AFTER_WAIT = { SELF | BLOCKERS }

Azure Synapse Analytics の構文:

DBCC SHRINKDATABASE
( database_name
     [ , target_percent ]
)
[ WITH NO_INFOMSGS ]

引数

{ database_name | database_id |0 }

データベースの名前やIDを縮小する。 値が0の場合は現在のデータベースを示します。

target_percent

縮小操作が完了した後にデータベースファイル内に残す空き容量の割合。

target_percentTRUNCATEONLYで指定すると、縮小操作がファイルの終わりで空き空間を解放しないことがあります。

NOTRUNCATE(ノットランケート)

ファイル末尾の割り当て済みページをファイル先頭の未割り当てページに移動します。 この操作により、ファイル内のデータが圧縮されます。 target_percent は省略可能です。 Azure Synapse Analytics では、このオプションはサポートされません。

ファイル末尾の空き領域はオペレーティング システムに返されず、ファイルの物理サイズは変わりません。 そのため、NOTRUNCATE を指定した場合、データベースが圧縮されていないように見えます。

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

トランケートのみ

ファイル末尾のすべての空き領域をオペレーティング システムに解放します。 ファイル内でのページの移動は行いません。 データ ファイルは、最後に割り当てられたエクステントを限度として圧縮されます。 Azure Synapse Analytics では、このオプションはサポートされません。

target_percentTRUNCATEONLYで指定すると、縮小操作がファイルの終わりで空き空間を解放しないことがあります。

NO_INFOMSGS付き

重大度レベル 0 から 10 のすべての情報メッセージを表示しないようにします。

縮小操作を使用した WAIT_AT_LOW_PRIORITY

対象:SQL Server 2022(16.x)以降のバージョン、Azure SQL Database、Azure SQL Managed Instance、Microsoft FabricのSQL Database

低優先度での待機機能は、縮小操作中のロック競合を減らします。 詳細については、「DBCC SHRINKDATABASE に関するコンカレンシーの問題を理解する」を参照してください。

この機能は、オンライン インデックス操作の WAIT_AT_LOW_PRIORITY に似ていますが、いくつかの違いがあります。

  • ABORT_AFTER_WAIT NONEオプションを指定することはできません。
  • MAX_DURATIONオプションは設定できません。 縮小操作の低優先度ロックタイムアウトは常に1分です。

WAIT_AT_LOW_PRIORITY

WAIT_AT_LOW_PRIORITYモードで縮小コマンドを実行すると、Sch-Sにスキーマ安定性()ロックが必要なクエリは縮小操作によってブロックされません。 しかし、縮小操作はIAMページの Sch-S ロックによってブロック可能です。 シュリンクは、必要なIAMページに対してスキーマ変更ロック(Sch-M)ロックを取得できた場合にのみ実行を続けます。

WAIT_AT_LOW_PRIORITYモードの縮小操作がSch-Sロックを保持する長期間実行のクエリによりこのロックを取得できない場合、縮小操作はエラー49516でタイムアウトします。例えば:Msg 49516, Level 16, State 1, Line 134 Shrink timeout waiting to acquire schema modify lock in WLP mode to process IAM pageID 1:2865 on database ID 5

{ ABORT_AFTER_WAIT = [ 自己 |ブロッカー ] }

  • SELF

    SELF は既定のオプションです。 現在実行中の縮小データベース操作を終了し、それ以上の行動を取らずに終了してください。

  • BLOCKERS

    ファイルの圧縮操作をブロックしているすべてのユーザー トランザクションを強制終了して、操作を続行できるようにします。 BLOCKERSオプションはログイン時にALTER ANY CONNECTIONまたはKILL DATABASE CONNECTIONの権限が必要です。

結果セット

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

列名 説明
DbId データベース エンジンで圧縮が試行されたファイルのデータベース識別番号。
FileId データベース エンジンで圧縮が試行されたファイルのファイル識別番号。
CurrentSize ファイルが現在占有する 8 KB ページの数。
MinimumSize ファイルが占有できる 8 KB ページの最小数。 この値は、ファイルの最小サイズまたは最初に作成されたサイズと一致します。
UsedPages ファイルが現在使用している 8 KB ページの数。
EstimatedPages データベース エンジンで推定されるファイル圧縮後の 8 KB ページの数。

データベース エンジンは縮小されていないファイルの行を表示しません。

解説

特定のデータベースに関するすべてのデータとログ ファイルを圧縮するには、DBCC SHRINKDATABASE コマンドを実行します。 特定のデータベースで一度に 1 つのデータまたはログ ファイルを圧縮するには、DBCC SHRINKFILE コマンドを実行します。

データベースの空き (未割り当て) 領域の現在の量を表示するには、sp_spaceused を実行します。

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

データベースは、そのデータベースの構成された最小サイズより小さくすることはできません。 データベースの最初の作成時に、最小サイズを指定します。 または、ファイル サイズ変更操作を使用して最後に明示的に設定したサイズを最小サイズにすることができます。 ファイル サイズ変更操作の例として、DBCC SHRINKFILEALTER DATABASE のような操作があります。

たとえば、データベースの最初の作成時にサイズを 10 MB に指定したとします。 その後、100 MB まで拡張したとします。 データベース内のすべてのデータを削除したとしても、データベースを縮小できる限界は 10 MB です。

NOTRUNCATEを実行する際に、TRUNCATEONLYまたはDBCC SHRINKDATABASEのオプションを指定できます。 どちらのオプションも指定しなければ、DBCC SHRINKDATABASENOTRUNCATE操作を実行した後にDBCC SHRINKDATABASETRUNCATEONLY操作を実行した場合と同じ結果になります。

圧縮されるデータベースは、シングル ユーザー モードになっていなくてもかいません。 データベースを圧縮している最中でも、他のユーザーがそのデータベースで作業することができます。システム データベースの場合も同様です。

データベースのバックアップ中、データベースを圧縮することはできません。 逆に、データベースの圧縮操作の進行中、データベースをバックアップすることはできません。

Azure SynapseのSQLプールでは、シュリンクコマンドの実行は避けてください。なぜなら、これはI/O負荷の多い操作であり、専用のSQLプール(旧SQL DW)をオフラインにしてしまう可能性があるからです。 このコマンドはデータウェアハウスのスナップショットのコストにも影響します。

既知の問題

適用対象:SQL Server、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics dedicated SQL pool

  • 2022 SQL Server(16.x)以前のバージョンでは、圧縮されたカラムストアセグメント内のLOBカラムタイプ(varbinary(max)varchar(max)、nvarchar(max))で使用されるページは、DBCC SHRINKDATABASEDBCC SHRINKFILEで移動できません。 詳細については、「 列ストア インデックスの新機能」を参照してください。

DBCC SHRINKDATABASE の動作

DBCC SHRINKDATABASE では、データ ファイルはファイルごとに圧縮されますが、ログ ファイルはすべてが 1 つの連続的なログ プールに存在するものとして圧縮されます。 ファイルは常に末尾から圧縮されます。

データベースに2つのログファイルとデータファイル1つがあると仮定します mydb。 各データ ファイルとログ ファイルのサイズは 10 MB で、データ ファイルに 6 MB のデータが含まれているとします。 それぞれのファイルについて、データベース エンジンによって目標サイズが計算されます。 この値は縮小後のファイルの目標サイズです。 DBCC SHRINKDATABASEをtarget_percentで指定すると、データベース エンジンは縮小後のファイル内でtarget_percent空きスペースのターゲットサイズを計算します。

たとえば、 を圧縮する場合に mydb を 25 に指定すると、データベース エンジンではデータ ファイルの目標サイズが 8 MB (6 MB のデータに 2 MB の空き領域を加えたもの) と計算されます。 したがって、データベース エンジンでは、データ ファイルの末尾 2 MB にあるすべてのデータがデータ ファイルの先頭 8 MB にある空き領域に移動されてから、ファイルが圧縮されます。

次に、mydb のデータ ファイルに 7 MB のデータが含まれているとします。 target_percent を 30 に指定した場合、このデータ ファイルは空き領域のパーセンテージが 30 になるように圧縮されます。 ただし、target_percent を 40 に指定しても、データ ファイルの現在の合計サイズに十分な空き領域を作成できないため、データ ファイルは圧縮されません。

別の考え方をすれば、目的の空き領域 40% にデータ ファイル最大容量の 70% (10 MB 中の 7 MB) を加算すると、100% を超えます。 30 より大きい値を target_percent に指定すると、データ ファイルは圧縮されません。 圧縮されない理由は、目的の空き領域のパーセンテージと、データ ファイルの現在の占有パーセンテージを加算した値が 100% を超えることです。

ログ ファイルの場合、データベース エンジンでは target_percent を使用してログ全体の目標サイズを計算します。 target_percent は圧縮操作後のログ内の空き領域の量になります。 その後、ログ全体の目標サイズは各ログ ファイルの目標サイズに変換されます。

DBCC SHRINKDATABASE では、各物理ログ ファイルの目標サイズへの圧縮がすぐに試行されます。 論理ログの目標サイズを超えて仮想ログに残る部分がいない場合、 DBCC SHRINKDATABASE ファイルは成功裏に切り詰められ、メッセージなしで終了します。 ただし、論理ログの一部が、目標サイズを超える仮想ログ内に存在する場合は、データベース エンジンにより、できるだけ多くの領域が解放され、その後に情報メッセージが発行されます。 このメッセージは、ファイルの最後に論理ログを仮想ログから移動させるためのアクションを記述しています。 アクションが実行された後、 DBCC SHRINKDATABASE を使って残りのスペースを解放します。

ログファイルは仮想ログファイルの境界にしか縮小できません。 だからこそ、ログファイルを仮想ログファイルのサイズより小さく縮小することは不可能です。 データベース エンジンはログファイルの作成や拡張時に仮想ログファイルのサイズを動的に選択します。

DBCC SHRINKDATABASE に関するコンカレンシーの問題を理解する

データベースの縮小コマンドやファイル縮小コマンドは、特にインデックスの再構築などのアクティブなメンテナンスや忙しいOLTP環境では並行性の問題を引き起こすことがあります。

例えば、ユーザーのクエリがインデックス割り当てマップ(IAM)ページのスキーマ安定性(Sch-S)ロックを取得し、完了するまで保持することがあります。 通常の使用中に容量を取り戻そうとする際、データベースやファイルの縮小操作は、IAMページの移動や削除時にスキーマ修正(Sch-M)ロックが必要となり、ユーザークエリに必要な Sch-S ロックをブロックします。 その結果、長時間実行されるクエリは縮小操作をブロックすることがあります。 この動作はまた、IAMページに Sch-S ロックが必要な新しいクエリが縮小操作の後ろにキューイングされることを意味し、この並行性の問題をさらに悪化させます。

2022年SQL Server(16.x)に導入された低優先度待機機能(low priority at shrink operations)は、WAIT_AT_LOW_PRIORITYモードでIAMページのスキーマ修正ロックを取ることでこの問題を解決します。 詳細については、「縮小操作を使用した WAIT_AT_LOW_PRIORITY」を参照してください。

Sch-SロックおよびSch-Mロックの詳細については、「トランザクションロックおよび行バージョン管理ガイド」をご覧ください。

ベスト プラクティス

データベースを圧縮する場合は次のことを考慮してください。

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

  • ほとんどのデータベースは、日常的な運用のためにある程度の空きスペースを必要とします。 データベースファイルを繰り返し縮小して再び拡大した場合、その増加は通常の操作に空きスペースが必要であることを示しています。 このような場合、データベースファイルを繰り返し縮小することは逆効果です。 縮小後に新しいスペースを割り当てるために必要なファイル成長はパフォーマンスを妨げる可能性があります。

  • 縮小操作はデータベース内のインデックスの断片化状態を保持せず、インデックス断片化を増加させるため、大規模なスキャンを用いるクエリの読み取りI/Oスループットが低下する可能性があります。

  • 特定の要件がない限り、 AUTO_SHRINK データベース オプションを ON に設定しないでください。

  • 大規模なデータベースのデータファイルを縮小する必要がある場合は、 ShrinkDriver のPowerShellスクリプトの使用を検討してください。 スクリプトは縮小プロセスを自動化・簡素化し、単一の観察可能かつ再開可能な操作に変えます。 スクリプトは複数のファイルを並列に縮小し、中断されると再試行し、実行中に詳細なステータスレポートを出力します。

トラブルシューティング

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

DBCC SHRINKDATABASE for database ID 9 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より古いスナップショットトランザクションが縮小操作をブロックします。 そのトランザクションは、圧縮操作によって完了した最後のトランザクションです。 また、transaction_sequence_num動的管理ビューのfirst_snapshot_sequence_numまたは列に15の値が含まれていることも示しています。 そのビューの transaction_sequence_num 列または first_snapshot_sequence_num 列に、圧縮操作により完了した最後のトランザクション (109) より低い番号が含まれている場合があります。 その場合、圧縮操作は、これらのトランザクションが完了するまで待機します。

問題を解決するには、以下のいずれかの方法があります。

  • 圧縮操作をブロックしているトランザクションを終了します。
  • 圧縮操作を終了します。 完了済みの作業は保持されます。
  • 何もせず、ブロックしているトランザクションが完了するまで圧縮操作を待機状態にしておきます。

アクセス許可

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

この記事のコードサンプルは、Azure Data SQL Samples Repository GitHub repositoryからダウンロードできるAdventureWorks2025またはAdventureWorksDW2025サンプルデータベースを使用しています。

A。 データベースを圧縮し、空き領域のパーセンテージを指定する

次の例では、UserDB ユーザー データベース内のデータ ファイルとログ ファイルのサイズを圧縮して、データベースの空き領域が 10% になるようにします。

DBCC SHRINKDATABASE (UserDB, 10);
GO

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

次の例では、AdventureWorks2025 サンプル データベース内のデータ ファイルとログ ファイルを、最後に割り当てられたエクステントまで圧縮します。

DBCC SHRINKDATABASE (AdventureWorks2025, TRUNCATEONLY);

C. Azure Synapse Analytics データベースを縮小する

DBCC SHRINKDATABASE (database_A);
DBCC SHRINKDATABASE (database_B, 10);

D. データベースを縮小する WAIT_AT_LOW_PRIORITY

次の例では、AdventureWorks2025 データベース内のデータ ファイルとログ ファイルのサイズを圧縮して、データベースの空き領域が 20% になるようにします。 1 分以内にロックを取得できない場合、圧縮操作は中止されます。

DBCC SHRINKDATABASE ([AdventureWorks2025], 20) WITH WAIT_AT_LOW_PRIORITY (ABORT_AFTER_WAIT = SELF);