MongoDBデータベースファイルのサイズの削減


165

私はかつて大規模だった(> 3GB)MongoDBデータベースを持っています。それ以来、ドキュメントは削除されており、それに応じてデータベースファイルのサイズが小さくなることを期待していました。

しかし、MongoDBは割り当てられたスペースを保持するため、ファイルは依然として大きいです。

私はあちこちを読んで、adminコマンドmongod --repairを使用して未使用のスペースを解放しましたが、このコマンドを実行するのに十分なディスクのスペースがありません。

未使用のスペースを解放する方法を知っていますか?


7
この質問は回答済みと見なされますか?さらにデータが必要ですか?
Gates VP、

2
バージョン2.8以降では、データ圧縮できるため、スペースを大幅に節約できます
サルバドールダリ

1
私も同じ問題を抱えていましたが、それを解決する最も簡単な方法は、copyDatabase()関数を使用してデータベースのコピーを作成し、次に元のデータベースをdb.dropDatabase()にコピーしてから、データベースを元の場所にコピーすることでした。私のデータベースはほとんど空でした、そして私がコピーをしたとき、実際に使用可能なデータだけがコピーされました。元のデータベースを削除すると、大きなファイルが削除されました。サーバーのディスク容量がすでに少なく、この操作では、この操作に必要な量よりもはるかに多くの空き容量が必要になるため、db.repairDatabase()を使用することはできませんでした。
user3892260 2016年

回答:


144

UPDATE:compactコマンド同じようWiredTigerに見える余分なディスク容量は、実際にOSにリリースされます


更新: v1.9以降、compactコマンドがあります。

このコマンドは、「インライン」で圧縮を実行します。それでも追加のスペースが必要になりますが、それほど多くはありません。


MongoDBは、次の方法でファイルを圧縮します。

  • ファイルを新しい場所にコピーする
  • 文書をループして再順序付け/解決する
  • 元のファイルを新しいファイルで置き換える

を実行するmongod --repairか、直接接続してを実行すると、この「圧縮」を実行できますdb.repairDatabase()

どちらの場合も、ファイルをコピーするためのどこかにスペースが必要です。現在、圧縮を実行するのに十分なスペースがない理由はわかりませんが、別のコンピューターにさらにスペースがある場合は、いくつかのオプションがあります。

  1. Mongoがインストールされている別のコンピューターにデータベースをエクスポートし(を使用mongoexport)、同じデータベースを(を使用してmongoimport)インポートできます。これにより、より圧縮された新しいデータベースが作成されます。これで、元のmongodデータベースファイルを新しいデータベースファイルで置き換えるのを止めることができます。
  2. 現在のmongodを停止し、データベースファイルをより大きなコンピューターにコピーして、そのコンピューターで修復を実行します。その後、新しいデータベースファイルを元のコンピュータに戻すことができます。

Mongoを使用して「適切な場所にコンパクト化」するための良い方法は現在ありません。そして、モンゴは間違いなくたくさんのスペースを吸い取ることができます。

圧縮のための現時点での最良の戦略は、マスター/スレーブセットアップを実行することです。次に、スレーブを圧縮し、スレーブを追い越して切り替えます。まだ少し毛むくじゃらです。おそらく、Mongoチームはより適切な場所での圧縮を考え出すでしょうが、私はそれが彼らのリストの上位にあるとは思いません。ドライブスペースは現在、安価であると想定されています(通常は安価です)。


回答をありがとうゲイツ副社長。あなたが言及した2つのオプションについて考えていました。しかし、そのようなことをする前に、コンパクトなインプレースソリューションが利用可能かどうかを知りたいと思いました。再度、感謝します。
Meuble

3
今日(2010-11-18)現在、ドワイト(ワシントンDCのMongoDCイベントで講演)は、データベースをオフラインにせずにコンパクト化する場合は、複製/ --repair /スイッチオーバーアプローチを推奨しました。
David J.

10
「私がしたようにしてはいけない」というヘッドアップを実行し、ルートとして--repairを実行します。ルートにdbファイルを変更します。どー。
トトロ

18
「コンパクト」のドキュメントには、「この操作によってファイルシステムで使用されるディスク容量が減ることはない」と書かれています。これが元の質問の解決策であることがわかりません。
エド・ノリス

元の質問を見ると、問題の一部には、修復を実行するにはデータが多すぎることが含まれます。ドライブの2/3を1つのDBで満たしている場合、修復を実行できません。新しく割り当てられたファイルは、新しいDBが完全に「コピーおよび修復」される前に残りのスペースを消費し、「切り替え」は起こりません。を使用するとcompact、少なくとも既存のファイルを適切な場所に保持できます。私は同意します。これは完全な解決策ではありませんが、段階的な改善です。
ゲイツ副社長

39

私は同じ問題を抱えており、コマンドラインでこれを行うだけで解決しました:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename

アサーション:15936コレクションdb.collectionの作成に失敗しました。Errmsg:例外:上限がtrueの場合にサイズを指定:<n>
tweak2

:ubuntu回帰のように見えます...ダンプファイルにメタデータが含まれています: "undefined"が含まれています...これらを削除するとインポートの問題が修正されます。
tweak2

2
私のデータベースはほぼディスク全体を記録しました。それは120 GB(ディスク160 GB)でした。コンパクトはファイルサイズを縮小せず、repairDatabaseはスペース不足のため不可能です。dbのmongodumpとdropDatabaseとmongorestoreの後、データベースサイズは40 GBになります。
Igor Benikov 16年

復元コマンドの小さな修正 mongorestore --db databasename dump/databasename
JERRY 2017年

34

Mongo v1.9 +はコンパクトをサポートしているようです!

> db.runCommand( { compact : 'mycollectionname' } )

ここのドキュメントを参照してください:http : //docs.mongodb.org/manual/reference/command/compact/

「repairDatabaseとは異なり、compactコマンドは、作業に2倍のディスク領域を必要としません。作業中に追加の少量の領域が必要です。さらに、compactはより高速です。」


3
@AnujGupta "repairDatabaseコマンドは、データベース内のすべてのコレクションを圧縮します。これは、各コレクションに対して個別にcompactコマンドを実行するのと同じです。" docs.mongodb.org/manual/reference/command/repairDatabase/…。したがって、repairDatabaseがサイズを縮小してコンパクトにする場合。毎週大量の削除と更新を行ってコレクションを圧縮しています。データベース全体ではなく、最初に必要なコレクションを対象にしているため、repariDatabaseよりもコンパクトが好きです。次に、dbファイルサイズのx2ではなく2GBの空き容量が必要です(私の場合は500GB)。
マジヤル2013年

1
これをチェックしてください: "MongoDBは、データを圧縮して最適なパフォーマンスを復元する2つの異なる方法を提供します。repairDatabaseとcompactです。RepairDatabaseは、データベースが比較的小さい場合、またはノードをかなり長期間ローテーションから解放する余裕がある場合に適しています。データベースのサイズとクエリのワークロードについては、すべてのコレクションに対して継続的な圧縮を実行する方が理にかなっています。」blog.parse.com/2013/03/26/always-be-compacting github.com/ParsePlatform/Ops/blob/master/tools/mongo_compact.rb
Maziyar

3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space-「repairDatabaseとは異なり、compactはファイルシステムのスペースを解放しません」。
Anuj Gupta 2014

4
@Maziyar OPは未使用のスペース解放したいと考えてrepairDatabasecompactます。これは、ではなくによって実現されます。compactスペースを解放せず、使用済みのスペースを最適化するだけで、スペースを削減しません。
Anuj Gupta 2014

5
mongo 3.0の時点で、WiredTigerストレージエンジンを使用している場合、スペースcompact 再利用します。
Gary

19

現在のデータベースのすべてのコレクションを圧縮する

db.getCollectionNames().forEach(function (collectionName) {
    print('Compacting: ' + collectionName);
    db.runCommand({ compact: collectionName });
});

13

完全な修復を実行する必要がある場合は、repairpathオプションを使用します。空き容量の多いディスクを指定してください。

たとえば、私のMacでは次のように使用しました。

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair

更新:MongoDBコアサーバーチケット4266ごとに--nojournal、エラーを回避するために追加が必要になる場合があります。

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal

1
これはうまくいきました。修理に必要な2倍のスペースがないため、NASをマウントしました。問題だけで、完了するまでに18時間かかりましたが、問題なく動作しました。必ず--nojouralフラグを追加してください。
zenocon


7

StorageEngineに基づく2つの方法を解決する必要があります。

1. MMAP()エンジン:

コマンド:db.repairDatabase()

注: repairDatabaseには、現在のデータセットのサイズに2ギガバイトを加えたサイズに等しい空きディスク領域が必要です。dbpathを保持するボリュームに十分なスペースがない場合は、別のボリュームをマウントして、それを修復に使用できます。repairDatabase用に別のボリュームをマウントする場合は、コマンドラインからrepairDatabaseを実行し、-repairpathスイッチを使用して一時的な修復ファイルを保存するフォルダーを指定する必要があります。例:DBサイズが120 GBであることを想像してください。(120 * 2)+2 = 242 GBのハードディスク容量が必要です。

別の方法でコレクションを行う方法: db.runCommand({compact: 'collectionName'})

2. WiredTiger: 自動的に解決されます。


6

MongoDBでのスペースの再利用についてはかなりの混乱があり、推奨されるプラクティスの中には、特定の配置タイプで実行するのが非常に危険なものがあります。以下の詳細:

TL; DR repairDatabaseは、ディスクの破損から回復しようとしているスタンドアロンのMongoDBデプロイメントからデータを回収しようとします。スペースが回復した場合、それは純粋に副作用です。スペースの回復は、を実行する上での主な考慮事項ではありませんrepairDatabase

スタンドアロンノードのスペースを回復する

WiredTiger:WiredTigerを使用するスタンドアロンノードの場合、実行compactするとOSにスペースが解放されますが、1つの注意点がありますcompact。MongoDB3.0.xのWiredTigerでのコマンドは、このバグの影響を受けました:SERVER-21833、MongoDB 3.2.3で修正されました。このバージョンの前はcompact、WiredTigerで警告なしに失敗することがありました。

MMAPv1: MMAPv1が機能する方法のため、MMAPv1ストレージエンジンを使用してスペースを回復するための安全でサポートされている方法はありません。compactMMAPv1では、データファイルを最適化し、新しいドキュメントに使用できるスペースを増やす可能性がありますが、OSにスペースを解放しません。

あなたはあり実行することができrepairDatabaseますが、完全にこの場合の影響を理解している場合、潜在的に危険なコマンドをするので、(下記参照します)repairDatabase、本質的に破損した文書を破棄することにより、データベース全体を書き換えます。副作用として、これにより、断片化のない新しいMMAPv1データファイルが作成され、スペースがOSに解放されます。

それほど冒険的な方法ではmongodumpありmongorestoreませんが、MMAPv1展開でも実行可能であり、展開のサイズによって異なります。

レプリカセットのスペースを回復する

レプリカセット構成の場合、スペースを回復する最善かつ最も安全な方法は、WiredTigerとMMAPv1の両方に対して初期同期を実行することです。

セット内のすべてのノードからスペースを回復する必要がある場合は、ローリング初期同期を実行できます。つまり、最終的にプライマリをステップダウンして初期同期を実行する前に、各セカンダリで初期同期を実行します。ローリング初期同期方法は、レプリカセットのメンテナンスを実行する最も安全な方法であり、ボーナスとしてダウンタイムも発生しません。

ローリング初期同期を実行できるかどうかは、展開のサイズにも依存することに注意してください。非常に大規模な展開の場合、最初の同期を実行することは現実的ではない可能性があるため、オプションはやや制限されます。WiredTigerを使用する場合、場合は、セットからセカンダリを1つ取り、スタンドアロンとして起動し、実行compactして、セットに再結合できます。

について repairDatabase

repairDatabaseレプリカセットノードでは実行しないでください。これは非常に危険です。repairDatabaseページでです。で説明し、以下で詳しく説明します。

repairDatabaseコマンドは何も修復しようとしないので、名前は少し誤解を招く可能性があります。このコマンドは、スタンドアロンノードでディスクが破損している場合に使用するためのものでした。でドキュメントが破損する可能性ます。

repairDatabaseコマンドは、より正確に「サルベージデータベース」として記述することができます。つまり、破損したドキュメントを破棄してデータベースを再作成し、データベースを起動可能な状態にして、そのままのドキュメントを復元できるようにします。

MMAPv1展開では、データベースファイルのこの再構築により、副作用として OSにスペースが解放されます。OSに領域を解放することが目的ではありませんでした。

repairDatabaseレプリカセットの結果

レプリカセットでは、MongoDBはセット内のすべてのノードに同一のデータが含まれていることを想定しています。repairDatabaseレプリカセットノードで実行すると、ノードに検出されない破損が含まれている可能性がありrepairDatabase、破損したドキュメントが忠実に削除されます。

予想通り、これにより、そのノードには残りのセットとは異なるデータセットが含まれます。更新がその単一のドキュメントにヒットした場合、セット全体がクラッシュする可能性があります。

さらに悪いことに、この状況が長期間休止状態になり、明確な理由なしに突然ストライキを起こすだけの可能性もあります。


5

大量のデータがコレクションから削除され、コレクションが削除されたスペースを新しいドキュメントに使用しない場合、このスペースをオペレーティングシステムに返して、他のデータベースまたはコレクションで使用できるようにする必要があります。ディスク領域を最適化して使用可能な空き領域を回復するには、圧縮または修復操作を実行する必要があります。

圧縮プロセスの動作は、MongoDBエンジンに次のように依存しています

db.runCommand({compact: collection-name })

MMAPv1

圧縮操作は、データファイルとインデックスを最適化します。ただし、オペレーティングシステムに領域を解放しません。この操作は、MongoDBで再利用するために、断片化を解消してより連続したスペースを作成するのに役立ちます。ただし、ディスクの空き容量が非常に少ない場合は、役に立ちません。

圧縮操作中は、最大2GBの追加ディスク容量が必要です。

圧縮操作中は、データベースレベルのロックが保持されます。

WiredTiger

WiredTigerエンジンはデフォルトで圧縮を提供し、MMAPv1よりもディスク容量を消費しません。

コンパクトプロセスは、空き領域をオペレーティングシステムに解放します。コンパクト操作を実行するには、最小限のディスク領域が必要です。WiredTigerは、データベースレベルのロックが必要なため、データベース上のすべての操作もブロックします。

MMAPv1のエンジン、コンパクトdoestは、オペレーティング・システムにスペースを返しません。未使用のスペースを解放するには、修復操作を実行する必要があります。

db.runCommand({repairDatabase: 1})

3

Mongodb 3.0以降には、新しいストレージエンジン-WiredTigerがあります。私の場合、スイッチングエンジンによってディスク使用量が100 Gbから25Gbに減少しました。


1

データベースファイルのサイズを縮小することはできません。データベースを「修復」している間、mongoサーバーがそのファイルの一部を削除することのみ可能です。大量のデータが削除されている場合、mongoサーバーは修復中に既存のファイルの一部を "解放"(削除)します。


1

一般に、repairDatabaseよりコンパクトです。しかし、コンパクトに対する修復の1つの利点は、クラスター全体に対して修復を実行できることです。コンパクト各シャードにログインする必要があり、これはちょっと面倒です。


1

同じ問題が発生したときに、mongoサーバーを停止し、コマンドで再び起動しました

mongod --repair

修復操作を実行する前に、HDDに十分な空き容量があることを確認する必要があります(最小-データベースのサイズ)


1

スタンドアロンモードでは、コンパクトまたは修復を使用できます。

シャードクラスターまたはレプリカセットの場合、私の経験では、プライマリでコンパクトを実行し、次にセカンダリをコンパクトにした後、プライマリデータベースのサイズは減少しましたが、セカンダリは減少しませんでした。セカンダリデータベースのサイズを小さくするために、メンバーの再同期を行うことができます。これを実行すると、セカンダリデータベースのサイズがプライマリデータベースよりもさらに小さくなることがわかります。compactコマンドは、コレクションを実際には圧縮していません。そのため、レプリカセットのプライマリとセカンダリを切り替えて、メンバーの再同期を再度行うことになりました。

私の結論は、シャード/レプリカセットのサイズを削減する最良の方法は、メンバーの再同期、プライマリセカンダリの切り替え、および再同期を行うことです。


0

シャードクラスターの場合、mongoDB -repairは推奨されません。

レプリカセット分割クラスターを使用している場合は、compactコマンドを使用します。これにより、すべてのコレクションのすべてのデータとインデックスファイルが書き換えられ、最適化されます。 構文:

db.runCommand( { compact : "collection_name" } )

force:trueとともに使用すると、compactはレプリカセットのプライマリで実行されます。 例えば db.runCommand ( { command : "collection_name", force : true } )

考慮すべきその他のポイント:-操作をブロックします。メンテナンスウィンドウで実行することをお勧めします。-レプリカセットが異なるサーバーで実行されている場合、各メンバーで個別に実行する必要があります-シャードクラスターの場合、compactは各シャードメンバーで個別に実行する必要があります。mongosインスタンスに対して実行できません。


-5

私がそれを行うことができた唯一の方法。既存のデータの安全性は保証されません。自己責任でお試しください。

データファイルを直接削除し、mongodを再起動します。

たとえば、ubuntu(データへのデフォルトパス:/ var / lib / mongodb)では、collection。#のような名前のファイルがいくつかありました。collection.0を保持し、他のすべてを削除しました。

データベースに重要なデータがない場合は、より簡単な方法のようです。


ファイルは<database_name>。<number>として保存されます(例:mydb.3)-コレクションはわかりません。
bobmarksie 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.