前書き
定期的なデータベースバックアップは、意図しないデータ損失イベントから保護するための重要なステップです。 一般に、バックアップには大きく2つのカテゴリがあります。ファイルシステムレベル(「物理」)バックアップと論理バックアップです。
ファイルシステムレベルのバックアップでは、基礎となるデータファイルのある時点でのスナップショットを作成し、スナップショットファイルにキャプチャされた状態を使用してデータベースをきれいに回復できるようにします。 これらは、特にLVM snapshotsなどのファイルシステムスナップショット、またはDigitalOcean Block Storage Snapshotsなどのブロックストレージボリュームスナップショットと組み合わせて使用する場合に、大規模なデータベースを迅速にバックアップするのに役立ちます。
論理バックアップには、ツールの使用が含まれます(例: mongodump
またはpg_dump
)を使用して、データベースからバックアップファイルにデータをエクスポートします。バックアップファイルは、対応する復元ツール(例: mongorestore
またはpg_restore
)。 多くの場合、バックアップおよび復元するデータをきめ細かく制御し、データベースのバージョンやインストール間でバックアップを移植できます。 論理バックアップツールは、メモリを介してバックアップされるすべてのデータを読み取るため、処理速度が遅くなり、特に大規模なデータベースの場合に重要な負荷が大きくなる可能性があります。
効果的なバックアップおよびリカバリ戦略の設計には、多くの場合、パフォーマンスへの影響、実装コスト、およびデータストレージコストとリカバリ速度、データ整合性、およびバックアップカバレッジのトレードオフが伴います。 最適なソリューションは、リカバリポイントと時間objectives、およびデータベースの規模とアーキテクチャによって異なります。
このガイドでは、組み込みの論理バックアップツールであるmongodump
を使用してMongoDBデータベースをバックアップする方法を示します。 次に、結果のシリアル化されたデータバックアップファイルを圧縮して、冗長性の高いオブジェクトストアであるDigitalOcean Spacesにアップロードする方法を示します。 また、Bashとcron
を使用してバックアップとアップロードの操作を定期的にスケジュールする方法を示し、最後にサンプルのデータ復旧シナリオで締めくくります。
このチュートリアルの終わりまでに、拡張可能な自動バックアップ戦略のフレームワークを実装して、アプリケーションがデータ損失に陥った場合に迅速に復旧できるようにします。 小規模から中規模のデータベースの場合、mongodump
を使用した論理バックアップにより、バックアップおよびリカバリするデータをきめ細かく制御できます。 これらの圧縮されたバックアップアーカイブをDigitalOcean Spacesに保存すると、耐久性のあるオブジェクトストアで容易に利用できるため、アプリケーションデータが保護され、データ損失イベントが発生した場合に迅速に回復できます。
[.note]#Note:mongodump
ツールを使用すると、特に負荷の高いデータベースでパフォーマンスに影響が出る可能性があります。 最初に、負荷をシミュレートした非本番データベースを使用してこの手順をテストし、このメソッドが本番デプロイメントで機能することを確認する必要があります。
#
前提条件
このガイドを開始する前に、次の前提条件が利用可能であることを確認してください。
-
Initial Server Setup with Ubuntu 16.04で詳しく説明されているように、sudo権限を持つ非rootユーザーのUbuntu16.04ドロップレット
-
実行中のMongoDB3.2以降のインストール(How to Install MongoDB on Ubuntu 16.04で詳しく説明されています)
-
How To Create a DigitalOcean Space and API Keyで詳しく説明されている、DigitalOceanスペースとAPI資格情報のセット。
-
Step 1 of How To Use Logrotate and S3cmd to Archive Logs to Object Storage on Ubuntu 16.04で説明されているようにインストールされた
s3cmd
コマンドラインファイル転送クライアント(2.X) -
How To Configure s3cmd 2.x To Manage DigitalOcean Spacesで詳しく説明されているように、スペースにアクセスするように構成された
s3cmd
Dropletにログインし、MongoDBを起動して実行し、スペースを作成したら、すぐに使用を開始できます。
[[step-1 -—- insert-test-data]] ==ステップ1—テストデータを挿入します
クリーンなMongoDBインストールから開始し、まだデータを保存していない場合は、テスト目的で、最初にいくつかのサンプルデータをダミーのrestaurants
コレクションに挿入する必要があります。 データベースにすでにいくつかのコレクションとドキュメントが保存されている場合は、この手順をスキップして、Step 2に進んでください。
まず、MongoDBシェルを使用して実行中のデータベースに接続します。
mongo
次のMongoシェルプロンプトが表示されます。
MongoDB shell version: 3.2.19
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
2018-04-11T20:30:57.320+0000 I CONTROL [initandlisten]
2018-04-11T20:30:57.320+0000 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-04-11T20:30:57.320+0000 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-04-11T20:30:57.320+0000 I CONTROL [initandlisten]
>
デフォルトでは、シェルはtest
データベースに接続します。
test
データベースに存在するコレクションを一覧表示しましょう。
show collections
データベースにはまだ何も挿入していないため、コレクションはなく、出力なしでプロンプトに戻ります。
ダミーのrestaurants
コレクションにドキュメントを挿入してみましょう。このコレクションは自動的に作成されます(まだ存在していないため)。
db.restaurants.insert({'name': 'Pizzeria Sammy'})
次の出力が表示されます。
OutputWriteResult({ "nInserted" : 1 })
これは、挿入操作が成功したことを示します。
コレクションをもう一度リストします。
show collections
新しく作成されたrestaurants
コレクションが表示されます。
Outputrestaurants
MongoDBシェルを終了するには、CTRL
+D
を押します。
データベースにサンプルデータを保存したので、バックアップする準備が整いました。
[[step-2 -—- use-mongodump-to-back-up-mongodb-data]] ==ステップ2 —mongodump
を使用してMongoDBデータをバックアップします
次に、組み込みのmongodump
ユーティリティを使用して、MongoDBデータベース全体を圧縮アーカイブファイルにバックアップ(または「ダンプ」)します。
まず、mongodump
によって作成されたアーカイブを保存するために、backup
という一時ディレクトリを作成しましょう。
mkdir backup
それでは、このMongoDBインスタンスのtest
データベースをtest_dump.gz
という圧縮アーカイブファイルにバックアップしましょう。 インスタンスに他のデータベースが含まれている場合は、--db
フラグの後にtest
を別のデータベース名に置き換えることができます。 --db
フラグを省略して、MongoDBインスタンスのallデータベースをバックアップすることもできます。
[.note]#Note:次のコマンドはターミナルから実行する必要があり、notはMongoシェルです。
#
mongodump --db test --archive=./backup/test_dump.gz --gzip
ここでは、--archive
フラグを使用して、すべてのデータを単一のアーカイブファイル(場所はarchive
パラメーターで指定)に保存することを指定し、--gzip
このファイルを圧縮することを指定するフラグ。 さらに、オプションで、--collection
または--query
フラグを使用して、アーカイブする特定のコレクションまたはクエリを選択できます。 これらのフラグの詳細については、mongodump
documentationを参照してください。
dumpコマンドを実行すると、次の出力が表示されます。
Output2018-04-13T16:29:32.191+0000 writing test.restaurants to archive './backup/test_dump.gz'
2018-04-13T16:29:32.192+0000 done dumping test.restaurants (1 document)
これは、テストデータが正常にダンプされたことを示しています。
次のステップでは、このバックアップアーカイブをオブジェクトストレージにアップロードします。
[[step-3 -—- upload-the-backup-archive-to-digitalocean-spaces]] ==ステップ3—バックアップアーカイブをDigitalOceanSpacesにアップロードします
このアーカイブをDigitalOceanSpaceにアップロードするには、Prerequisitesにインストールして構成したs3cmd
ツールを使用する必要があります。
最初にs3cmd
構成をテストし、バックアップスペースへのアクセスを試みます。 このチュートリアルでは、スペース名としてmongo-backup-demo
を使用しますが、スペースの実際の名前を入力する必要があります。
s3cmd info s3://mongo-backup-demo/
次の出力が表示されます。
Outputs3://mongo-backup-demo/ (bucket):
Location: nyc3
Payer: BucketOwner
Expiration Rule: none
Policy: none
CORS: none
ACL: 3587522: FULL_CONTROL
これは、接続が成功し、s3cmd
がオブジェクトをスペースに転送できることを示しています。
手順2で作成したアーカイブをput
コマンドを使用してSpaceに転送しましょう。
s3cmd put ./backup/test_dump.gz s3://mongo-backup-demo/
ファイル転送の出力が表示されます。
Outputupload: './backup/test_dump.gz' -> 's3://mongo-backup-demo/test_dump.gz' [1 of 1]
297 of 297 100% in 0s 25.28 kB/s done
転送が完了すると、スペースのコンテンツを一覧表示して、ファイルがスペースに正常に転送されたことを確認します。
s3cmd ls s3://mongo-backup-demo/
バックアップアーカイブファイルが表示されます。
Output2018-04-13 20:39 297 s3://mongo-backup-demo/test_dump.gz
この時点で、test
MongoDBデータベースのバックアップに成功し、バックアップアーカイブをDigitalOceanSpaceに転送しました。
次のセクションでは、cron
を使用してスケジュールできるように、Bashを使用して上記の手順をスクリプト化する方法について説明します。
[[step-4 -—- create-and-test-backup-script]] ==ステップ4—バックアップスクリプトの作成とテスト
MongoDBデータベースを圧縮アーカイブファイルにバックアップし、このファイルをSpaceに転送したので、これらの手動手順を1つのBashスクリプトに結合できます。
バックアップスクリプトを作成
まず、mongodump
コマンドとs3cmd put
コマンドを組み合わせたスクリプトを作成し、いくつかのロギング( `echo`sを使用)のように、いくつかの追加のベルとホイッスルを追加します。
好みのテキストエディタで空のファイルを開きます(ここではnano
を使用します)。
nano backup_mongo.sh
次のコードスニペットを貼り付け、関連する値を更新して、独自のスペース、データベース、およびファイル名を参照するようにしてください。 ファイルをbackup_mongo.sh
と呼びますが、このファイルには任意の名前を付けることができます。 このセクションの最後で完全なスクリプトを見つけることもできます。
このスクリプトを1つずつ見ていきましょう。
backup_mongo.sh
#!/bin/bash
set -e
...
ここで、#!/bin/bash
は、スクリプトをBashコードとして解釈するようにシェルに指示します。 set -e
は、スクリプトコマンドのいずれかが失敗した場合、インタプリタにすぐに終了するように指示します。
backup_mongo.sh
...
SPACE_NAME=mongo-backup-demo
BACKUP_NAME=$(date +%y%m%d_%H%M%S).gz
DB=test
...
このセクションでは、後で使用する3つの変数を設定します。
-
SPACE_NAME
:バックアップファイルをアップロードするDigitalOceanスペースの名前 -
BACKUP_NAME
:バックアップアーカイブの名前。 ここでは、基本的な日時文字列に設定します。 -
DB
:スクリプトがバックアップするMongoDBデータベースを指定します。 MongoDBインスタンス全体(すべてのデータベース)をバックアップする場合、この変数は使用されません。
backup_mongo.sh
...
date
echo "Backing up MongoDB database to DigitalOcean Space: $SPACE_NAME"
echo "Dumping MongoDB $DB database to compressed archive"
mongodump --db $DB --archive=$HOME/backup/tmp_dump.gz --gzip
echo "Copying compressed archive to DigitalOcean Space: $SPACE_NAME"
s3cmd put $HOME/backup/tmp_dump.gz s3://$SPACE_NAME/$BACKUP_NAME
...
次に、(ログ記録の目的で)日付と時刻を出力し、上記でテストしたmongodump
コマンドを実行してバックアップを開始します。 もう一度、バックアップアーカイブを~/backup/
に保存します。
次に、s3cmd
を使用して、このアーカイブをこれら2つのSPACE_NAME
変数とBACKUP_NAME
変数で指定された場所にコピーします。 たとえば、スペース名がmongo-backup-demo
で、現在の日時が2018/04/12 12:42:21
の場合、バックアップには180412_124221.gz
という名前が付けられ、mongo-backup-demo
スペースに保存されます。 。
backup_mongo.sh
...
echo "Cleaning up compressed archive"
rm $HOME/backup/tmp_dump.gz
echo 'Backup complete!'
ここでは、バックアップアーカイブをスペースに正常にコピーしたので、~/backup
ディレクトリから削除します。最終出力は、バックアップが完了したことを示します。
これらすべてのコードスニペットを組み合わせた後、完全なスクリプトは次のようになります。
backup_mongo.sh
#!/bin/bash
set -e
SPACE_NAME=mongo-backup-demo
BACKUP_NAME=$(date +%y%m%d_%H%M%S).gz
DB=test
date
echo "Backing up MongoDB database to DigitalOcean Space: $SPACE_NAME"
echo "Dumping MongoDB $DB database to compressed archive"
mongodump --db $DB --archive=$HOME/backup/tmp_dump.gz --gzip
echo "Copying compressed archive to DigitalOcean Space: $SPACE_NAME"
s3cmd put $HOME/backup/tmp_dump.gz s3://$SPACE_NAME/$BACKUP_NAME
echo "Cleaning up compressed archive"
rm $HOME/backup/tmp_dump.gz
echo 'Backup complete!'
完了したら、このファイルを必ず保存してください。
次に、このスクリプトをテストして、すべてのサブコマンドが機能することを検証します。
バックアップスクリプトのテスト
backup_mongo.sh
スクリプトをすばやく実行してみましょう。
まず、スクリプトを実行可能にします。
chmod +x backup_mongo.sh
次に、スクリプトを実行します。
./backup_mongo.sh
次の出力が表示されます。
OutputMon Apr 16 22:20:26 UTC 2018
Backing up MongoDB database to DigitalOcean Space: mongo-backup-demo
Dumping MongoDB test database to compressed archive
2018-04-16T22:20:26.664+0000 writing test.restaurants to archive '/home/sammy/backup/tmp_dump.gz'
2018-04-16T22:20:26.671+0000 done dumping test.restaurants (1 document)
Copying compressed archive to DigitalOcean Space: mongo-backup-demo
upload: '/home/sammy/backup/tmp_dump.gz' -> 's3://mongo-backup-demo/180416_222026.gz' [1 of 1]
297 of 297 100% in 0s 3.47 kB/s done
Cleaning up compressed archive
Backup complete!
バックアップシェルスクリプトが正常に作成され、cron
を使用してスケジュールを設定できるようになりました。
[[step-5 -—- schedule-daily-backups-using-cron]] ==ステップ5—Cronを使用して毎日のバックアップをスケジュールする
バックアップスクリプトの夜間実行をスケジュールするには、Unixライクなオペレーティングシステムに組み込まれているジョブスケジューリングユーティリティであるcron
を使用します。
最初に、バックアップスクリプトのログを保存するディレクトリを作成します。 次に、バックアップスクリプトをcrontab(cron
の構成ファイル)に追加して、cron
が毎晩実行するようにスケジュールします。 cron
は任意の定期的な頻度をサポートしているため、オプションで毎週または毎月のバックアップをスケジュールできます。
ロギングディレクトリを作成する
バックアップスクリプトのログファイルを保存するディレクトリを作成しましょう。 これらのログにより、バックアップスクリプトを定期的にチェックしてすべてが正常であることを確認し、一部のコマンドが失敗した場合にデバッグできます。
/var/log
にmongo_backup
サブディレクトリを作成します(慣例により、ロギングに使用されます)。
sudo mkdir /var/log/mongo_backup
ここで、そのディレクトリをUnixユーザーに書き込み可能にします。 この場合、ユーザーの名前はsammyですが、サーバーのsudo権限を持つ関連するroot以外のユーザー名を使用する必要があります。
sudo chown sammy:sammy /var/log/mongo_backup
Unixユーザーsammyが/var/log/mongo_backup
に書き込むことができるようになりました。 cronジョブはsammyとして実行されるため、ログファイルをこのディレクトリに書き込むことができます。
スケジュールされたcronjobを作成しましょう。
Cronjobを作成
cronジョブを作成するには、「crontab」と呼ばれる、スケジュールされたジョブのリストを含むファイルを編集します。複数のcrontabがあり、ユーザーごとに1つあり、/etc/crontab
にシステム全体のcrontabがあることに注意してください。 このチュートリアルでは、ユーザーsammyとしてバックアップスクリプトを実行します。ユースケースに応じて、システム全体のcrontabから実行することを選択できます。
編集のためにcrontabを開きます。
crontab -e
次のメニューが表示され、好みのテキストエディターを選択できます。
Outputno crontab for sammy - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/ed
2. /bin/nano <---- easiest
3. /usr/bin/vim.basic
4. /usr/bin/vim.tiny
Choose 1-4 [2]: no crontab for sammy - using an empty one
ご希望のエディターを選択してください。 nano
を選択するには、2
と入力します。 次に、コメントアウトされたセクションの後に、ファイルに次の行を追加します。
クロンタブ-e
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
0 2 * * * /home/sammy/mongo_backup.sh >>/var/log/mongo_backup/mongo_backup.log 2>&1
crontabの最後に必ず末尾の改行を含めるようにしてください。 ファイルを保存して閉じます。
次の出力が表示されます。
Outputno crontab for sammy - using an empty one
crontab: installing new crontab
これで、バックアップスクリプトは毎朝午前2時に実行されます。 stdout
とstderr
(出力ストリームとエラーストリーム)の両方がパイプ処理され、前に作成したログディレクトリのmongo_backup.log
というログファイルに追加されます。
0 2 * * *
(cron構文では毎晩午前2:00に実行)を希望のバックアップ頻度と時間に変更できます。 cronとその構文の詳細については、How To Use Cron To Automate Tasks On A VPSに関するチュートリアルを参照してください。
バックアップが機能することを確認するために、このチュートリアルをクイックリカバリ演習で締めくくります。
[[step-6 -—- perform-a-test-recovery]] ==ステップ6—テストリカバリを実行します
バックアップ戦略には、定期的にテストされる回復手順を含める必要があります。 ここでは、DigitalOceanスペースにアップロードした圧縮バックアップファイルからの復元を簡単にテストします。
まず、スペースからMongoDBドロップレットのホームディレクトリにtest_dump.gz
をダウンロードします。
s3cmd get s3://mongo-backup-demo/test_dump.gz
次の出力が表示されます。
Outputdownload: 's3://mongo-backup-demo/test_dump.gz' -> './test_dump.gz' [1 of 1]
297 of 297 100% in 0s 1305.79 B/s done
このチュートリアルを新しいMongoDBインスタンスで開始した場合、バックアップしたデータベースはtest
データベースのみであったことを思い出してください。
デモンストレーションのために、このテストデータベースを削除して、クリーンリストアを実行できるようにします。 この最初の手順を実行しない場合、復元手順では元のドキュメントが検出されるため、スキップされます。 特定のユースケースでは、新しいドキュメントのみの復元が許容される場合がありますが、このチュートリアルの目的のために、空のデータベースへの完全な復元を明示的にテストしたいと思います。
mongo
シェルを使用してMongoDBインスタンスに接続します。
mongo
ここで、use
はtest
データベースであり、MongoDBインスタンスから削除します。
use test
db.dropDatabase()
test
のドロップを確認する次の出力が表示されます。
Output{ "dropped" : "test", "ok" : 1 }
ここで、mongo
シェルを終了し、mongorestore
コマンドを実行します。
mongorestore --gzip --archive=test_dump.gz --db test
ここでは、ソースバックアップファイルが圧縮され、「アーカイブファイル」形式であることを指定し(mongodump
を呼び出すときに--archive
フラグと--gzip
フラグを使用したことを思い出してください)、 test
データベースに復元したい。
次の出力が表示されます。
Output2018-04-16T23:10:07.317+0000 creating intents for archive
2018-04-16T23:10:07.453+0000 reading metadata for test.restaurants from archive 'test_dump.gz'
2018-04-16T23:10:07.497+0000 restoring test.restaurants from archive 'test_dump.gz'
2018-04-16T23:10:07.541+0000 restoring indexes for collection test.restaurants from metadata
2018-04-16T23:10:07.541+0000 finished restoring test.restaurants (1 document)
2018-04-16T23:10:07.541+0000 done
これは、test
の復元が成功したことを示しています。
結論として、最初のrestaurants
データが正常に復元されたことを確認しましょう。
MongoDBシェルを開き、restaurants
コレクションをクエリします。
db.restaurants.find()
このチュートリアルの最初のステップで保存したオブジェクトが表示されます。
Output{ "_id" : ObjectId("5ace7614dbdf8137afe60025"), "name" : "Pizzeria Sammy" }
これで、このMongoDBバックアップ戦略の実装とテストが正常に完了しました。
結論
このチュートリアルでは、夜間の論理的なMongoDBバックアップの戦略を実装およびテストする方法を学びました。
このガイドは、さまざまな方法で拡張または変更できます。 いくつかの簡単な提案を次に示します。
-
リカバリポイントの目標(RPO)に応じて、データリカバリウィンドウに合わせて、推奨されるバックアップ頻度を増減することができます。
-
別の便利な追加機能は、バックアップスクリプトサブコマンドが失敗した場合にトリガーされるアラート機能です(例: この機能は、定期的に監視されるアラート受信ボックスにメールを送信できます)。
-
このスクリプトは、スペースオブジェクトの削除を処理しません。 たとえば、6か月ほど前のバックアップを一掃することもできます。
-
本番ユースケースによっては、より複雑なbackup rotation schemeを実装することもできます。
mongodump
プロシージャでは、ダンプされたすべてのデータをすばやく読み取る必要があるため、このバックアップ方法は、中小規模のデータベース、特に特定のコレクションや結果セットなどの部分的なバックアップに最適です。 大規模な展開には、ファイルシステムレベルのバックアップをお勧めします。 ファイルシステムレベルのMongoDBバックアップの詳細については、How To Back Up MongoDB Using Droplet Snapshotsに関するこのチュートリアルを参照してください。 MongoDBデータベースをバックアップするさまざまな方法の詳細については、MongoDB manualを参照してください。
このチュートリアルで紹介するソリューションは、mongodump
を活用してバックアップデータのカバレッジをきめ細かく制御し、DigitalOceanSpacesを活用して費用効果が高く耐久性のある長期データストレージを実現します。 mongodump
バックアップユーティリティの詳細については、MongoDBマニュアルのreference pageを参照してください。 DigitalOcean Spacesの詳細については、An Introduction To DigitalOcean Spacesを参照してください。