REMP開発中に誤爆して本番環境上の開発者のプレイリストがうっかり意図しない内容に更新してしまうというケースが生じたため、デイリーでとっているmongo DBのバックアップから復旧させてみました。*1
行いたいのは、特定のユーザのプレイリストのみの復旧なので、単純にmongorestoreする訳にはいかないので、方法として以下の手順で復旧させました。
- バックアップファイルを展開する
- ローカル環境のmongo DBに一度まるごとリストアする
- ローカルにリストアしたmongo DBから該当ユーザのプレイリスト情報(特定のコレクション内の1ドキュメント)をJSON形式で保管する
- ローカルで出力したJSONをサーバ側のmongo DBでインポートする
以下、復旧した際のメモをば…。
バックアップファイルを展開する
まず、保管されていたバックアップファイルを展開します。
[ローカル環境]
% tar xvzf rempdb-20120228.tgz
rempdb-20120228/
rempdb-20120228/rempdb/
rempdb-20120228/rempdb/library.bson
(中略)
ローカル環境のmongo DBにリストアする
前段で展開されるバックアップファイルの中身のファイルがJSONであれば、直接テキストファイルなので編集して該当するユーザのコレクションのみの抽出も行えるのですが、BSONのため一度手元のmongo dbに取り込んで処理することにしました。
リストアはmongorestoreコマンドを使えばよいので、リファレンスに従って操作して、
[ローカル環境]
% mongorestore -d rempdb --drop rempdb-20120228/rempdb
connected to: 127.0.0.1
Wed Feb 29 17:43:12 rempdb-20120228/rempdb/library.bson
Wed Feb 29 17:43:12 going into namespace [rempdb.library]
Wed Feb 29 17:43:12 dropping
(中略)
これで手元のmongo dbにバックアップファイルの内容がリストアされました。
(コマンドの末尾のパスはバックアップファイルの展開先)
該当ユーザのプレイリスト(コレクション内のドキュメント)をJSON出力する
サーバ側で復旧させたいユーザのREMPのプレイリストを抽出するためmongoexportコマンドを利用して、該当ドキュメントのJSONファイルを出力させます。
mongoexportコマンドを使うとDBやコレクションを特定し且つ、クエリを与えてヒットしたドキュメントのJSONだけを出力することができます。
[ローカル環境]
% mongoexport -d rempdb -c library -q "{uid:'1234567'}" -o playlist.json
connected to: 127.0.0.1
exported 1 records
中身を見てみると。。。
[ローカル環境]
% cat playlist.json
{ 〜 , "uid" : "1234567" }
と、クエリで抽出されたドキュメントのJSONファイルがそのまま出力されているはずなので、その内容がリストア対象であることを確認します。
サーバ側で稼動しているmongo DBへローカル環境で出力したJSONをリストアする
ローカル環境でまるごとリストアしたDBから出力した特定のドキュメントのJSONをサーバ側でインポートします。
mongoimportコマンドを利用することでJSONファイルをmongo DBにインポートすることができるので、以下の様にコマンドを入力。
[サーバ環境(リストアしたいDB側)]
% mongoimport -d rempdb -c library playlist.json --upsert
connected to: 127.0.0.1
imported 1 objects
これでサーバ上のmongo DBへバックアップファイルから取得した特定のドキュメントのみを復旧させることができました。
上記の方法でリストアできない (あるいは、--upsertオプションが効かない場合)
mongoのバージョンが古い場合、mongoimportコマンドに --upsertオプションが無い場合は、一旦ドキュメントを消してインポートすると良い…のかな。
MongoDB shell version: 1.*.*
connecting to: ***
>db.**.remove({uid:"1234567"})
>
で一度消して、
% mongoimport -d rempdb -c library playlist.json
connected to: 127.0.0.1
imported 1 objects
といった具合。
*1:あ、念のためですが他のユーザの方に影響はありません。開発用のクライアントを操作している際に生じたケースです。