前回はインデックスの作成を行い、パフォーマンスの改善を達成しました。今回はデータベースのメンテナンスを実施したいと思います。

Introduction

長期にわたってデータベースを利用していると、色々問題が発生してきます。
不要なインデックス、ログ、ジャーナルファイル、未使用領域の削除等。
そういう無駄をそぎ落とし、使い始めた頃の輝きを取り戻すためにメンテナンスが必要です。

NoSQLに限らずRDBMSでも当然の機能です。

Explanation

Compact

compactによれば、

Rewrites and defragments all data and indexes in a collection. On WiredTiger databases, this command will release unneeded disk space to the operating system.

訳: コレクション内のすべてのデータ、インデックスの書き直しとデフラグを実行します。WiredTigerデータベースにおいて、このコマンドはオペレーティングシステムへ不要なディスク領域を変換します。

と言っています。
最後の一文が魅力的です。

ちょっと補足ですが、WiredTiger とは、MongoDBで採用しているストレージモデルです。
MongoDBでは下記の3モデルを利用可能です。

  • MMAPv1 Storage Engine
  • WiredTiger Storage Engine
  • In-Memory Storage Engine

MMAPv1 Storage Engine

MongoDB 3.2までは既定のストレージエンジンだったモデルです。

WiredTiger Storage Engine

MongoDB 3.0から採用された新ストレージエンジン。64bitで利用可能です。
マルチバージョン同時事実行コントロールを採用。オペレーション実行時、WiredTigerはデータのその時点でのスナップショットをトランザクションに提供します。スナップショットはインメモリーデータの一貫したビューを表します。

In-Memory Storage Engine

MongoDB Enterprise 3.2から始まった、64bitビルドで利用可能な。ベータテストを目的としたエンジンです。いくつかのメタデータを除き。インメモリストレージエンジンはディスク上にデータを維持せず、ディスクI/Oを避けるため、データベースオペレーションの予測可能な待ち時間を許容します。

実際にCompactコマンドを実行します。
対象はコレクションです。
現在私の環境には、5つのデータベースにそれぞれ1つのコレクションが存在します。
それらすべてにCompactコマンドを実施します。

コマンドの実行は下記になります。

WARNING
Always have an up-to-date backup before performing server maintenance such as the compact operation.

訳: 警告 compactオペレーションのようなサーバメンテナンスを実行する前に、常に最新のバックアップを取得してください

1
2
3
4
5
6
7
8
$ mongo --port 27017
> use admin
switched to db admin
> db.auth("admin","password")
1
> use hogehoge
> db.runCommand ( { compact: 'foo'})
{ "ok" : 1 }

データベースの修正が必要なので、admin権限で一度認証を通すためにadminデータベースにつないで認証します。
その後、対象のデータベースにつないでコレクション名を指定してコマンドを発行します。
私の環境だとすぐに結果が返ってきました。
下記は実行前後のデータベースの情報をmongo-expressで確認した結果です。

コレクション SmallObjectData
Before
SmallObjectData
After
MiddleObjectData
Before
MiddleObjectData
After
LargeObjectData
Before
LargeObjectData
After
LargeData
Before
LargeData
After
Data
Before
Data
After
Collections (incl. system.namespaces) 1 1 1 1 1 1 1 1 1 1
Data Size 51.0 mb 51.0 mb 80.1 gb 80.1 gb 100 gb 100 gb 100 gb 100 gb 51.0 mb 51.0 mb
Storage Size 14.4 mb 14.4 mb 4.12 gb 4.12 gb 8.22 gb 8.22 gb 8.22 gb 8.22 gb 14.4 mb 14.3 mb
Avg Obj Size # 51.0 bytes 51.0 bytes 80.1 kb 80.1 kb 100 kb 100 kb 100 kb 100 kb 51.0 bytes 51.0 bytes
Objects # 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000
Extents # 0 0 0 0 0 0 0 0 0 0
Indexes # 2 2 2 2 2 2 1 1 1 1
Index Size 19.7 mb 19.7 mb 19.7 mb 19.7 mb 19.7 mb 19.7 mb 8.91 mb 8.91 mb 8.92 mb 8.92 mb

変化した個所が1箇所しかないですし、微々たる変化です。
ストレージフォルダのサイズも 19.5 GB (20,976,769,972 バイト) から 19.5 GB (20,976,930,330 バイト) になって、むしろ増えています。

Insert,Select,インデックスの設定くらいしかしていないと、変化しないのでしょうね。

Conclusion

かなり端折ったところもありますが、これで一区切りつけます。
自分としては、Insert,Select.Dropができればそれでよいデータベースが欲しく、SQLとか面倒だと思って、NoSQLの検討を始めた次第でしたが、思った以上にボリュームの多い内容になりました。

結論としては、MongoDBは、私には向かないかなぁ、って思いました。
MongoDBの採用するドキュメント型の仕組みは、キーと値がセットになっているがゆえに、型がわからないと復元もままならないご様子。
そこまで厳密な型付けは求めていません。
とはいうものの、拡張していくことを考えると、これはこれで問題ないのでしょうけど。

また、Node.jsに踏み込むとは、始めた時は全く考えていませんでした。
こういう思わぬ驚きがあるのが、テクノロジーの世界なんですね。