時間の経過とともに、データの挿入、更新、削除などのデータベース操作によりディスクが断片化し、有効なディスク使用率が低下します。compact コマンドは、不要になったディスク領域をオペレーティングシステムに解放しようと試みます。本トピックでは、ディスク領域の再利用方法およびストレージ効率の向上方法について説明します。
推奨:より簡単な操作と低い業務影響を実現するため、コンソールベースの ストレージ分析 機能をご利用ください。
ストレージ分析は、非表示メンバーでのみ断片化を回収します。プライマリノードまたはセカンダリノードを圧縮するには、まずフェールオーバーを実行して、それらを非表示メンバーに変換してください。
ストレージ分析は、MongoDB 4.2(≥4.0.23)、MongoDB 4.4(≥5.0.7)、または MongoDB 5.0 以降を必要とします。
Primary/Secondary ノードに対して手動制御または直接的な compact 操作が必要な場合は、以下に示す通り compact コマンドをご利用ください。
事前準備
ご利用のインスタンスは WiredTiger ストレージエンジンを使用している必要があります。
データのバックアップ を実行してから compact を実行してください。
compact を実行するタイミング
データベース操作により時間の経過とともにディスクが断片化し、有効な使用率が低下します。以下のシナリオで compact を実行してください。
大量のデータを一括削除した後
大量のデータを削除すると、将来の書き込みのためにディスク領域が確保されたままになります。これにより、未使用の断片化領域が発生します。
手動による削除や自動 TTL 有効期限切れでは、compact はトリガーされません。ディスク領域の再利用は手動で実行する必要があります。
長時間実行される高頻度書き込みワークロード
挿入、更新、削除操作を頻繁に実行すると、断片化領域が時間とともに蓄積します。
ディスク領域の制約があり、断片化率が 20 % を超える場合
ディスク使用率が 85~90 % に達し、かつ断片化率が 20 % を超える場合、compact を実行することでディスク使用量を削減できます。
クイックスタート: コレクションをコンパクト化
本セクションでは、ディスク領域を迅速に解放するための最短手順を示します。
レプリカセットおよびシャードクラスターインスタンスでは、業務への影響を最小限に抑えるため、セカンダリノード で compact を実行してください。完全なワークフローについては、「Primary/Secondary ノードの compact」をご参照ください。
ステップ 1:インスタンスへの接続
Mongo Shell を使用して接続します。
レプリカセットインスタンス(影響を最小限にするため、セカンダリノードに接続)
ステップ 2:対象データベースへの切り替え
use <database_name>show dbs を実行して、データベースの一覧を表示します。
ステップ 3:compact コマンドの実行
compact の実行前後で、対象データベースにて db.runCommand({collStats: "<collection_name>"}) を実行し、compact の効果を検証できます。
レプリカセットおよびスタンドアローン
db.runCommand({compact:"<collection_name>"})show tables を実行して、コレクションの一覧を表示します。
MongoDB 4.2 以前の Primary ノードでは、force:true を追加してください。
db.runCommand({compact:"<collection_name>",force:true})正常終了時の戻り値:
{ "ok" : 1 }シャードクラスター
以下の例では mongo shell の構文を使用しています。mongosh 1.x および 2.x の構文については、「Primary/Secondary ノードの compact」をご参照ください。
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},$queryOptions: {$readPreference: {mode: 'secondary'}}})パラメーター:
<Shard ID>: MongoDB コンソール > インスタンス 基本情報 > シャード一覧 で確認できます。<collection_name>: コレクション名です。$readPreference: {mode: 'secondary'}: compact 操作を Primary ノードへの影響を避けるため、セカンダリノードにルーティングします。
正常終了時の戻り値:
{ "ok" : 1 }ディスクストレージ領域の確認
ストレージサイズおよび断片化率の確認
compact の実行が必要かどうかを評価し、その効果を検証するため、コレクションを含むデータベースで、compact の実行前後で以下のコマンドを実行します。
db.runCommand({collStats: <collection_name>})主なフィールド:
size: コレクション内の非圧縮データの合計サイズです。storageSize: コレクションに割り当てられたディスク領域の合計サイズです。freeStorageSize: 再利用可能なストレージ領域の量です(MongoDB 4.4 以降で利用可能)。
断片化率 = freeStorageSize / storageSize
この比率が高いほど、断片化が深刻であることを示します。
詳細については、「collStats の出力」をご参照ください。
再利用可能な領域の見積もり
コレクションを含むデータベースに切り替えた後、以下のコマンドを実行します。
db.<collection_name>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]例:
db.test_collection.stats().wiredTiger["block-manager"]["file bytes available for reuse"]サンプル出力:
207806464これは、約 207,806,464 バイト(約 198 MB)の領域が再利用可能であることを示します。
Primary/Secondary ノードの compact
レプリカセットおよびスタンドアローン
スタンドアローンインスタンスには単一の Primary ノードがあります。ピーク時を避けた時間帯に Primary ノードで直接 compact を実行してください。
レプリカセットインスタンスには Primary、Secondary、および任意の ReadOnly ノードが存在します。Primary ノードおよび Secondary ノードすべてで compact を実行する必要があります。ReadOnly ノードが存在する場合は、同様のコマンドで compact を実行してください。
業務への影響を最小限に抑えるため、以下の推奨ローリングメンテナンスワークフローに従ってください。
推奨ワークフロー:
まず、セカンダリノードの compact を実行します。
フェールオーバー を実行して、Primary を Secondary に切り替えます。
新しい Secondary(元の Primary)の compact を実行します。
存在する場合は、ReadOnly ノードの compact を実行します。
compact コマンド:
db.runCommand({compact:"<collection_name>"})MongoDB 4.2 以前のレプリカセットにおける Primary ノードの場合:db.runCommand({compact:"<collection_name>",force:true})例:
db.runCommand({compact:"orders"})シャードクラスター
シャードクラスターでは、ユーザーのデータを格納しない mongos および config サーバーではなく、シャードノードでのみ compact を実行してください。
シャードクラスターにおける ReadOnly ノードでは、compact はサポートされていません。業務への影響を低減するため、Primary ノードを直接 compact するのではなく、以下のワークフローに従ってください。
推奨ワークフロー:
各シャード内のセカンダリノードを最初にコンパクト化します。
各シャードで フェールオーバー を実行します。
新しいセカンダリノード(元の Primary)の compact を実行します。
セカンダリノードの compact:
mongosh 2.x
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"}},{readPreference: "secondary"})mongosh 1.x
db.getMongo().setReadPref('secondary')
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"}})mongo shell
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},$queryOptions: {$readPreference: {mode: 'secondary'}}})パラメーター:
<Shard ID>: MongoDB コンソール > インスタンス 基本情報 > シャード一覧 で確認できます。<collection_name>: コレクション名です。$readPreference: {mode: 'secondary'}: compact 操作を Primary ノードへの影響を避けるため、セカンダリノードにルーティングします。
Primary ノードの compact(推奨しません):
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>",force:true}})force パラメーターは、MongoDB 4.2 以前で必須です。
重要な考慮事項
パフォーマンスへの影響
MongoDB 4.4 より前のバージョン
compactは、データベース全体をロックします。実行中は、すべての読み取りおよび書き込み操作がブロックされます。
断片化が著しい場合、実行時間が長くなり、Hidden ノードで大きなレプリケーション遅延が発生する可能性があります。
推奨事項:ピーク時を避けた時間帯に実行する、Oplog のサイズを調整する、または MongoDB 4.4 以降へのスペックアップ を実施してください。
MongoDB 4.4 以降
compactは、読み取りおよび書き込み操作をブロックしません。実行中のパフォーマンスに影響が出る可能性があります。
推奨事項:ピーク時を避けた時間帯に実行してください。
ノード再構築リスク
以下のバージョンでは、自動的なノード再構築がトリガーされる可能性があります。
バージョン | リスク |
MongoDB 3.4(全バージョン) | ノードが RECOVERING 状態になり、ヘルスチェックのしきい値を超えると再構築がトリガーされる可能性があります。 |
MongoDB 4.0(全バージョン) | 上記と同じです。 |
MongoDB 4.2(≤4.0.22) | 上記と同じです。 |
MongoDB 4.4(≤5.0.6) | 上記と同じです。 |
後続バージョン:ノードは SECONDARY 状態を維持し、再構築はトリガーされません。
バージョンの詳細については、「MongoDB マイナーバージョンのリリースノート」をご参照ください。
compact が効果を発揮しない場合
compact コマンドは、以下の条件で効果を発揮しません。
物理的なコレクションサイズが 1 MB 未満の場合。
断片化率が 20 % 未満の場合。
ファイルの先頭 80 % 領域において、利用可能な領域が 20 % 未満の場合。
ファイルの先頭 90 % 領域において、利用可能な領域が 10 % 未満の場合。
その他の考慮事項
実行時間: データ量およびシステムのワークロードによって異なります。
領域の解放: 解放される領域は、利用可能な領域よりも少なくなる場合があります。次の compact を実行する前に、直前の
compactが完了していることを確認してください。ディスクが満杯の状況: ディスクが満杯でインスタンスがロックされている場合でも、
compactを実行できます。
トラブルシューティング
エラー:「Compaction interrupted due to cache eviction pressure」
原因: 古いバージョンで小規模仕様のインスタンスでは、キャッシュ圧力により compact が中止される場合があります。
解決策: システム負荷が低いピーク時を避けた時間帯に実行してください。
関連ドキュメント
付録:ディスク断片化の理解
断片化が発生する仕組み
ApsaraDB for MongoDB インスタンスからデータを削除すると、そのデータが使用していたストレージ領域は再利用可能な状態としてマークされます。新規データは以下のいずれかの方法で格納されます。
利用可能な領域に直接格納される
ファイルサイズを拡張したうえで、ファイル末尾に格納される
この結果、ファイル内に未使用の利用可能領域が散在することとなり、これがディスク断片化です。
断片化の影響
断片化が進むと、有効なディスク使用率が低下します。
例:
ディスクサイズ:100 GB
断片化領域:20 GB
業務データ:60 GB
報告されるディスク使用率:80 %(60 GB + 20 GB)
有効なディスク使用率:60 %(業務データのみ)
断片化した 20 GB の領域は「使用中」としてカウントされますが、実際にはデータは含まれていません。
コマンドリファレンス
compact コマンドの完全なドキュメントについては、以下をご参照ください。