2026年7月11日

2026年7月11日

MongoDBのmongodumpで自動バックアップを設定する方法(cron・世代管理・復元確認)

mongodump の自動バックアップは、「専用のバックアップユーザーを作る」「パスワードをコマンドラインに出さない設定ファイルで1本のアーカイブに書き出す」「cron で回して古い世代を消す」「定期的に別環境へ復元して確かめる」の4点を押さえれば、小〜中規模の MongoDB で安定して運用できます。この記事では、シェルスクリプトと cron を使った具体的な設定手順と、復元までの確認方法を説明します。

mongodump が向いている規模と、向いていないケース

mongodump はデータベースの中身を BSON 形式で書き出す論理バックアップのツールです。MongoDB 4.4 以降は「MongoDB Database Tools」として本体とは別パッケージで配布されており、サーバー本体のバージョンとは別のバージョン番号(100.x 系)で更新されています(2026年10月現在)。インストール済みかどうかは mongodump --version で確かめられます。

公式ドキュメントでも、mongodump/mongorestore は小規模なデプロイ向けの手軽な手段であり、大きなシステムのバックアップには理想的ではない、という位置づけです。理由は次のとおりです。

  • 全データを読み出すため、実行中はディスク I/O とメモリ(ワーキングセット)を圧迫する
  • インデックスは定義だけが保存され、復元時に作り直すので、データ量が多いと復元に時間がかかる
  • シャードクラスタで書き込みが続いている状態では、整合性のとれた時点を取りにくい

目安として、ダンプと復元がメンテナンスの許容時間内に収まるかどうかで判断してください。収まらない規模になったら、ファイルシステムのスナップショットや、MongoDB Atlas のクラウドバックアップのようなマネージドな仕組みを検討します。

手順1:バックアップ専用ユーザーを作る

管理者ユーザーをそのままバックアップに使うと、認証情報が漏れたときの被害が大きくなります。MongoDB には組み込みロールの backup(取得用)と restore(復元用)があるので、取得側には backup だけを付けたユーザーを作ります。mongosh で admin データベースに接続して実行します。

use admin
db.createUser({
  user: "backupUser",
  pwd: passwordPrompt(),   // 対話入力にしてシェル履歴に残さない
  roles: [ { role: "backup", db: "admin" } ]
})

passwordPrompt() を使うと、パスワードを画面と履歴に残さずに入力できます。復元は頻度が低い作業なので、restore ロールのユーザーは別に用意し、必要なときだけ使う運用が安全です。

手順2:認証情報を設定ファイルに分ける

mongodump --password=... のようにパスワードを引数で渡すと、実行中に ps コマンドで他のユーザーから見えてしまいます。Database Tools 100.3.0 以降では --config オプションで YAML ファイルを読み込めるので、パスワードを含む接続文字列はそこに置きます。

# /etc/mongo-backup/config.yaml(所有者 root、パーミッション 600)
uri: mongodb://backupUser:your-password@127.0.0.1:27017/?authSource=admin
sudo install -d -m 700 /etc/mongo-backup
sudo chmod 600 /etc/mongo-backup/config.yaml

パスワードに @ や : などの記号が含まれる場合は、URI の中ではパーセントエンコードが必要です。ここでつまずくと「Authentication failed」になるので、まず手動で mongodump --config=/etc/mongo-backup/config.yaml --archive=/tmp/test.gz --gzip を1回実行し、エラーが出ないことを確かめてから自動化に進みます。

手順3:バックアップスクリプトを書く

出力形式は、ディレクトリにコレクションごとのファイルを並べる方式と、--archive で1つのファイルにまとめる方式があります。自動バックアップでは、転送や世代管理がしやすい --archive と --gzip の組み合わせが扱いやすいです。

#!/usr/bin/env bash
# /usr/local/bin/mongo-backup.sh
set -euo pipefail

BACKUP_DIR="/var/backups/mongodb"
KEEP_DAYS=14
STAMP="$(date +%Y%m%d-%H%M%S)"
OUT="${BACKUP_DIR}/mongo-${STAMP}.archive.gz"

mkdir -p "$BACKUP_DIR"
chmod 700 "$BACKUP_DIR"

# 一時ファイルに書き、成功したときだけ正式な名前にする
mongodump --config=/etc/mongo-backup/config.yaml \
  --archive="${OUT}.part" --gzip --oplog

mv "${OUT}.part" "$OUT"

# 空や極端に小さいファイルは失敗とみなす
if [ "$(stat -c %s "$OUT")" -lt 1024 ]; then
  echo "backup file too small: $OUT" >&2
  exit 1
fi

# 古い世代を削除
find "$BACKUP_DIR" -name 'mongo-*.archive.gz' -mtime +"$KEEP_DAYS" -delete
find "$BACKUP_DIR" -name '*.part' -mtime +1 -delete

echo "backup ok: $OUT"

ポイントをいくつか補足します。

  • --oplog はレプリカセットのメンバーに対して全体をダンプするときに使え、ダンプ中に発生した書き込みも記録して、ある一時点に揃った状態で復元できるようにします。スタンドアロン構成では使えず、--db や --collection で対象を絞った場合とも併用できないので、その場合はこの行から外してください。
  • レプリカセットなら、URI に readPreference=secondary を付けてセカンダリから読むと、プライマリへの負荷を減らせます。
  • set -euo pipefail と一時ファイル名(.part)の組み合わせで、途中で失敗したダンプが「正常なバックアップ」の顔をして残るのを防いでいます。

スクリプトを置いたら sudo chmod 700 /usr/local/bin/mongo-backup.sh とし、手動で一度実行して、出力ファイルができることを確認します。

手順4:cron で自動実行する

root の crontab(sudo crontab -e)に登録します。前回の実行が長引いたときに二重起動しないよう、flock で排他をかけておくと安心です。

# 毎日 3:15 に実行。ログは追記
15 3 * * * flock -n /run/mongo-backup.lock /usr/local/bin/mongo-backup.sh >> /var/log/mongo-backup.log 2>&1

crontab の中では % が改行として解釈されるため、date +%Y%m%d のような書式はこの例のようにスクリプト側に書きます。systemd を使っているサーバーなら、systemd タイマーにしても同じことができ、journalctl でログを追えるのが利点です。

cron は失敗しても黙って止まるので、「動いているつもりで何週間も取れていなかった」という事態が起こりがちです。ログの最終行を定期的に見る、失敗時にメールやチャットへ通知する、外部の死活監視サービスへ成功時だけ通知を送る、といった仕組みを1つは用意してください。

手順5:サーバーの外へコピーする

同じサーバーのディスクにしかバックアップがないと、ディスク故障やサーバーの乗っ取りで本体と一緒に失われます。作成したアーカイブは、オブジェクトストレージや別サーバーへ転送します。転送前に暗号化するなら、gpg --symmetric や age などで暗号化してから送る方法があります。暗号化の鍵やパスフレーズはバックアップと同じ場所に置かないことが大切です。

手順6:復元して確かめる

バックアップは復元できて初めて意味があります。本番とは別の検証用インスタンスに対して、定期的に復元を試してください。

# 検証用インスタンスへ復元(--drop は既存コレクションを消してから入れる)
mongorestore --uri="mongodb://restoreUser@127.0.0.1:27018/?authSource=admin" \
  --archive=/var/backups/mongodb/mongo-20261018-031500.archive.gz \
  --gzip --oplogReplay --drop

# 特定のデータベースだけ戻す場合
mongorestore --uri="mongodb://restoreUser@127.0.0.1:27018/?authSource=admin" \
  --archive=/var/backups/mongodb/mongo-20261018-031500.archive.gz \
  --gzip --nsInclude='appdb.*'

URI にパスワードを書かなければ、実行時に入力を求められます。--oplogReplay は --oplog 付きで取得したダンプを復元するときに指定します。--drop は対象コレクションを削除してから復元するため、接続先を本番と取り違えると大きな事故になります。実行前にポート番号とホスト名を指差しで確認するくらいの慎重さで扱ってください。

復元後は、mongosh で主要コレクションの countDocuments() を本番と比べる、アプリケーションから実際に読み書きしてみる、といった確認をします。復元にかかった時間も記録しておくと、障害時の見積もりに使えます。

よくあるつまずき

  • Authentication failed:authSource=admin の付け忘れ、パスワード内の記号のエンコード漏れが典型です。
  • --oplog のエラー:スタンドアロンのサーバーや、対象を絞ったダンプでは使えません。
  • ディスクが一杯になる:保持日数とダンプサイズから必要容量を計算し、df -h で余裕を確認します。ダンプ先をデータと同じディスクにしない構成が望ましいです。
  • バージョンの組み合わせ:Database Tools は対応するサーバーバージョンが決まっています。サーバーを更新したときは、ツール側の対応表も公式ドキュメントで確認してください。

まとめ

  • mongodump は小〜中規模向け。ダンプと復元が許容時間に収まらなくなったらスナップショットやマネージドバックアップを検討する
  • backup ロールだけを持つ専用ユーザーを作り、パスワードは --config の YAML ファイルに分けて 600 で保護する
  • --archive --gzip で1ファイルにまとめ、レプリカセットなら --oplog で時点を揃える
  • cron と flock で定期実行し、世代削除と失敗通知まで組み込む
  • サーバーの外へコピーし、検証用インスタンスへの復元を定期的に試す

お気軽にご相談ください

お見積りへ お問い合わせへ
▲