ver2.0からの機能であるcompactコマンドについて調べたのでまとめ
(ver2.2で内部的な動きに少し変更あり)
http://docs.mongodb.org/manual/reference/command/compact/
基本はここの日本語訳
Compactコマンド
The compact command rewrites and defragments a single collection. Additionally, the command drops all indexes at the beginning of compaction and rebuilds the indexes at the end.
- 1つのコレクションに対して rewrites and defragments を行う
- そのコレクションに貼られているindexを全部dropして貼り直す
- RDBで言うところのバキューム
実行方法
開始
db.runCommand ( { compact: '<collection>'})
db.runCommand ( { compact: '<collection>', [option]})
終了
db.killOp()
(もしくは処理が完了する前にサーバーをrestartする)
- ジャーナル機能を有効にしている場合、compactコマンドの処理を途中で止めてもジャーナルデータは整合性が保たれていて有効(indexは手動で振り直す必要がある)。
- ジャーナル機能を有効にしていない場合、途中終了した場合のデータの一貫性は保証できない。
- いずれにせよ 途中停止すると空き領域が使用不可能になる可能性がある 。その場合、空き領域をの復元のためにcompactコマンドを再実行して完了させなければいけない。
Option
force
- force = true にするとprimary nodeに対してcompactコマンドを実行できる,ただし primary nodeに対して実行されるその他の命令は全てエラーになる
paddingFactor, paddingBytes
- ver2.2からのオプション
- padding sizeを決める(paddingFactorは計算式の定数, paddingBytesはバイトサイズ指定)
- document size + padding size = record size,
- データが更新されるごとにサイズが増えることが予測されている場合は padding sizeの確保がパフォーマンスに影響する
- デフォルト値(paddingについて指定なし)だと、全ての paddingが除去される。
- " This may impact performance if the documents grow regularly."
- 将来的に追加されるコレクションやデータに対しての影響はない
Note
repairDatabaseとの比較
- repairDatabaseコマンドと比較して、ディスク容量を使用しない・(repairDatabaseよりは)速い。
- しかし、高速とはいえず、他のDBをブロックするので(ver.2.2以前)定期メンテ以外での使用は避けるべき。
- compactコマンドは 実行中に追加のディスクスペースは必要ないが、repairDatabaseと異なりファイルシステムの空き領域を開放しない
replica setとの関係
- セカンダリに対してcompactコマンドを実行するのが望ましい(プライマリに対して実行するときはforceオプションを使う)
- セカンダリに対してcompactコマンドを実行すると、クライアントからのアクセスを防ぐため、自動的に「リカバリー(回復中ディスク)」になる。実行が終了したら自動的にセカンダリに戻る。
- sample https://github.com/mongodb/mongo-snippets/blob/master/js/compact-example.js
- compactコマンドの実行結果は波及しない (プライマリでのコマンド実行結果がセカンダリにコピーされない)
- それぞれのDBに個別にcompactコマンドを実行する必要がある
Disk Sizeについて
compact may increase the total size and number of our data files, expecially when run for the first time. However, this will not increase the total colletion storage space since storage size is the amount of data allocated within the database files, and not the size/number of the files on the file system.
- compactコマンド 初回実行時は合計サイズやデータファイル数が増加するかもしれない がこれはDBファイルに割り当てられたストレージサイズであり、ファイルシステムのサイズではない。
その他
- コマンド実行前に全バックアップを取ること
- 実行中のログは mongod log fileで確認できる。もしくは db.currentOp() を他のシェルから実行してのぞける
- compact処理の前後でcollstatsコマンドを実行するとコレクションのストレージサイズがどう変化するかを確認することができる
- compactコマンドは 他の処理を全てブロックする (ver2.2からは自分のDBの処理のみブロックする)
- compactコマンドはmongodに対して発行されるコマンド。Sharding環境では、メンテナンス時にそれぞれのshardに対してcompactコマンドを実行すること。
- もともとpadding領域がないcappedコレクションに対してcompactコマンドを実行してもサイズ圧縮はできない。cappedコレクションのドキュメントはフラグメント化の影響を受けない。
実行結果
全てのコレクション・全てのRepSetに対してcompactコマンドを実行するスクリプトを作成して流してみました。
実行結果は以下
- storageSize => 25% 増
- fileSize => 10% 増
- numExtents => 75% 減
- indexSize => 30% 減
あまり頻繁に更新されないコレクションが多かったことや、1回目のコマンド実行だったことが影響しているのかなぁ。