要約:緊急対応
WiredTiger error: write failed: No space left on deviceというエラーが発生した場合、MongoDBサーバーのディスク容量が不足していることを意味します。MongoDBを迅速にオンラインに戻すには、すぐにディスク容量を解放する必要があります。以下に迅速なチェックリストを示します。
- ディスク使用量の確認:
df -hを使用して、満杯になっているパーティションを特定します。 - 大きなファイル/フォルダの特定:
sudo du -sh /path/to/directory/*を使用して、何が容量を消費しているかを調べます。特に/var/lib/mongodbと/var/logに注意してください。 - OSログのクリア: 通常
/var/logにある古いシステムログを削除または切り詰めます。 - MongoDBログのクリア: 古いMongoDBログファイル(例:
/var/log/mongodb内)をローテーションまたは削除します。 - 不要なファイルの削除: 即座の運用に不可欠ではない古いバックアップ、一時ファイル、またはテストデータをすべて削除します。
- ディスク容量の増強: 永続的な解決策として、クラウドプロバイダーまたはVM設定を使用してディスクボリュームを拡張します。
詳細な根本原因
WiredTiger error: write failed: No space left on deviceというメッセージは非常に明確で、システムのディスクが完全に満杯であることを示しています。これは、MongoDBのWiredTigerストレージエンジンがこれ以上データを書き込めないことを意味します。WiredTigerは、MongoDBバージョン3.2以降のデフォルトストレージエンジンであり、データファイル、インデックスファイル、ジャーナルファイルなど、ディスク上でのデータの保存方法を管理します。
ディスク容量が不足すると、WiredTigerは以下の重要な操作を実行できなくなります:
- 新しいデータを書き込んだり、既存のドキュメントを更新したりできません。
- インデックスエントリを作成または更新できません。
- データ永続性と回復に不可欠なジャーナルファイルに書き込めません。
- 一時的なディスク容量を必要とする内部操作を実行できません。
この問題はいくつかの要因から発生する可能性があります:
- 急激なデータ増加: データベースが予想よりもはるかに速く拡張した可能性があります。
- 大きなログファイル: MongoDBログまたはシステムログ(
syslogやjournaldなど)が、利用可能なすべての容量を消費した可能性があります。例えば、journalctlのログファイルは、管理されていないと数ギガバイトにまで膨れ上がる可能性があります。 - 未回収の領域: データを削除しても、必ずしもすぐにオペレーティングシステムに容量が解放されるわけではありません。WiredTigerは事前に容量を割り当て、内部的に再利用します。さらに、断片化により、データファイル内にかなりの内部空き容量があっても、ファイルが大きく見えることがあります。
- スナップショット/バックアップ: 同じディスクに保存されている古いデータベースのバックアップやボリュームスナップショットが、かなりの容量を消費している可能性があります。
- 一時ファイル: 同じサーバー上の他のアプリケーションが、大きな一時ファイルを生成した可能性があります。
このエラーが発生すると、MongoDBは通常、書き込み操作に応答しなくなります。読み取り操作は一時的に機能するかもしれませんが、ジャーナル更新のような内部書き込みも最終的には失敗します。当面の目標は、MongoDBを正常に戻すのに十分なディスク容量を解放することです。
修正アプローチ
1. 現在のディスク使用量を診断する
他の何をするよりもまず、実際に何がディスクを占有しているのかを理解することが重要です。
df -h
このコマンドは、すべてのマウントされたファイルシステムのディスク容量使用量を示します。100%(またはそれに非常に近い)満杯になっているパーティションを特定してください。
sudo du -sh /var/lib/mongodb
sudo du -sh /var/log
sudo du -sh /tmp
du -shを使用して、主要なディレクトリのディスク使用量を要約します。MongoDBのデータディレクトリ(デフォルトでは/var/lib/mongodb)は通常、主要な容疑者であり、しばしば数百ギガバイトを消費することがあります。また、システムログやアプリケーションログのために/var/logを、一時ファイルのために/tmpをチェックしてください。これらは数十ギガバイトを占める可能性があります。
2. MongoDB以外のデータをクリアする(一時的な緩和策)
MongoDB以外の領域をクリアすることは、特にMongoDBのデータディレクトリだけが問題ではない場合に、データベースを再び動作させるための最も速い方法となることがよくあります。
-
システムログのクリア:
sudo journalctl --vacuum-size=500M # ジャーナルログを500MBのみ保持 sudo journalctl --vacuum-time=7d # 過去7日間のログのみ保持 sudo apt autoremove # Ubuntu/Debianの場合、不要なパッケージを削除 sudo yum clean all # CentOS/RHELの場合、パッケージキャッシュをクリア
-
**一時ファイルのクリア:**
```bash
sudo rm -rf /tmp/*
/tmpからファイルを削除する際は注意が必要です。一部のアプリケーションがアクティブに使用している可能性があるためです。ただし、使用されなくなった古いファイルを削除することは一般的に安全です。
- 古いバックアップ/スナップショットの削除: 同じボリュームにバックアップを保存している場合、それらを別のストレージ場所に移動するか、不要になった古いものを削除してください。
3. MongoDB固有のクリーンアップ
3.1. MongoDBログのローテーション/クリア
MongoDBログは非常に大きくなり、すぐにディスク容量を消費する可能性があります。Linux上でlogrotateのようなツールを使用してログローテーションを設定するか、手動で古いログファイルをローテーションして削除する必要があります。
# MongoDBを停止(ディスク満杯でまだ停止していない場合)
sudo systemctl stop mongod
# 現在のログファイルをバックアップに移動(または不要なら削除)
sudo mv /var/log/mongodb/mongod.log /var/log/mongodb/mongod.log.old
# MongoDBを再起動
sudo systemctl start mongod
MongoDBは新しいmongod.logファイルを作成します。MongoDBが正しく起動することを確認した後、mongod.log.oldを安全に削除できます。
MongoDBを再起動せずにログをローテーションするには、adminデータベースに接続して以下を実行します:
db.adminCommand({ logRotate: 1 })
このコマンドは現在のログファイルの名前を変更し、新しいファイルを作成します。その後、ファイルシステムから古いローテーションされたログファイルを手動で削除できます。
3.2. コレクション/データベースの圧縮(Compact)
WiredTigerは内部的にディスク容量をインテリジェントに再利用します。そのため、ドキュメントを削除しても、オペレーティングシステムレベルでデータファイルがすぐに縮小されるとは限りません。compactコマンドは、データファイル内の未使用領域をデフラグして再利用するのに役立ちます。特定のコレクションまたはデータベース全体に対して実行できます。
警告: 圧縮(compacting)は非常にリソースを消費し、CPUとI/Oに負荷をかけ、一時的にパフォーマンスを低下させる可能性があります。大規模なコレクションの場合、このプロセスにはかなりの時間がかかり、操作中にコレクションのサイズと同等の空きディスク容量を必要とします。これはメンテナンス期間中にスケジュールするか、レプリカセット内のセカンダリノードで実行するのが最適です。
// 特定のコレクションを圧縮(大規模コレクションに推奨)
db.runCommand({ compact: "myCollection" })
// データベース全体を圧縮(大規模データベースでは極めて注意して使用)
db.runCommand({ compact: 1 })
圧縮後、df -hとdu -sh /var/lib/mongodbで再度ディスク容量を確認することを忘れないでください。
3.3. 不要なデータの削除
古い、未使用のコレクションやデータベース全体がある場合、それらを削除することは、直接的かつしばしば大幅に容量を解放する方法となります。これは永続的なアクションであるため、データに関して不確実な点がある場合は、常に信頼できるバックアップがあることを確認してください。
// コレクションを削除
db.myOldCollection.drop()
// データベース全体を削除
use myOldDatabase
db.dropDatabase()
3.4. データベースの修復(最終手段)
--repairオプションはデータベースをゼロから再構築し、容量を再利用し、潜在的な破損を修正できます。しかし、これは抜本的な措置です。完了するには、現在のデータディレクトリのサイズと同等以上の空きディスク容量が必要であり、かなりのダウンタイムも伴います。
警告: 重要なこととして、レプリカセットの場合、--repairを実行するよりも、健全なプライマリからセカンダリノードを再同期する方が一般的にずっと安全です。プライマリで--repairを実行すると、必然的にかなりのダウンタイムが発生します。
# MongoDBを停止
sudo systemctl stop mongod
# 修復を実行(データディレクトリのサイズ以上の十分な空き容量があることを確認)
mongod --dbpath /var/lib/mongodb --repair
# MongoDBを起動
sudo systemctl start mongod
4. ディスク容量を増やす(恒久的な解決策)
最終的に、最も堅牢で長期的な解決策は、MongoDBインスタンスにより多くのディスク容量をプロビジョニングすることです。
-
クラウドプロバイダー(AWS、Azure、GCP): 通常、ダウンタイムなしでEBSボリューム(AWS)、マネージドディスク(Azure)、または永続ディスク(GCP)のサイズを変更できます。例えば、AWS EBSボリュームを100GBから200GBに増やすことができます。その後、OS上でファイルシステムを拡張する(例:
resize2fsまたはxfs_growfs)必要があります。# クラウドコンソール/APIでディスクサイズを増やした後 # ext4ファイルシステムの場合: sudo resize2fs /dev/sda1 # /dev/sda1を実際のデバイスに置き換えてください # XFSファイルシステムの場合: sudo xfs_growfs /mount/point # /mount/pointを実際のマウントポイント(例: /)に置き換えてください
-
**仮想マシン/オンプレミス:** これには、新しい物理ディスクの追加、既存のLVMボリュームの拡張、またはデータをより大きなドライブに完全に移行することが含まれる場合があります。
### 5. WiredTiger圧縮の設定(予防策)
WiredTigerはコレクションとインデックスの両方に対して堅牢な圧縮オプションを提供しており、ディスク容量の使用量を大幅に削減できます。これは将来のデータ増加に対する予防策であり、すでに満杯になったディスクの即時修正ではないことに留意してください。
新しいコレクション/インデックスのデフォルト圧縮を設定したり、既存のコレクション/インデックスの圧縮を変更したりできます:
```javascript
// 新しいコレクションのデフォルト圧縮を設定(mongod.conf内)
storage:
wiredTiger:
engineConfig:
defaultCollectionConfig:
blockCompressor: snappy # または zlib, zstd, none
defaultIndexConfig:
blockCompressor: snappy
// 既存のコレクションの圧縮を変更
db.runCommand({
collMod: "myCollection",
storageEngine: {
wiredTiger: {
configString: "block_compressor=zlib"
}
}
})
既存のコレクションに圧縮を適用することは、そのすべてのデータを書き換えることを意味します。これは時間のかかるプロセスであり、かなりのI/Oリソースを消費します。したがって、これは計画されたメンテナンス期間中またはセカンダリノードで実行することを検討するのが最適です。
検証手順
これらの修正を適用したら、ディスク容量が実際に回復され、MongoDBが正しく機能していることを確認することが重要です。
-
ディスク容量の確認:
df -h
ディスクパーティションに十分な空き容量があること(理想的には10~20%の空き)を確認します。
-
**MongoDBログの確認:** `/var/log/mongodb/mongod.log`をレビューし、新しいエラーがないか、MongoDBが正常に再起動して接続を受け入れているかを確認します。
-
**書き込み操作の実行:** MongoDBに接続し、小さな書き込み操作を実行して、エラーなしでデータを書き込めることを確認します。
```javascript
use admin
db.testWrites.insertOne({ timestamp: new Date(), message: "Disk space test successful" })
その後、ログにWiredTiger errorメッセージがないことを確認します。
-
データベースステータスの監視: レプリカセットのステータス(該当する場合)を確認し、すべてのメンバーが健全で
PRIMARYまたはSECONDARY状態であることを確認します。rs.status()
## 参考資料
- [MongoDB Manual: WiredTigerストレージエンジン](https://www.mongodb.com/docs/manual/core/wiredtiger/)
- [MongoDB Manual: compactコマンド](https://www.mongodb.com/docs/manual/reference/command/compact/)
- [MongoDB Manual: logRotateコマンド](https://www.mongodb.com/docs/manual/reference/command/logRotate/)
- [MongoDB Manual: WiredTiger圧縮設定](https://www.mongodb.com/docs/manual/reference/configuration-options/#storage.wiredTiger.engineConfig.defaultCollectionConfig.blockCompressor)

