はじめに
あくまでも「私の環境はこれでどうにかなりました」というお話なので、全ての環境に適用できるものではないと思っております。ご理解ください。
本記事に出てくる用語等に誤りがあったらすみません。
この物語の舞台
-
背景
他社で作成されたスマートフォンアプリを移譲されることになり、それに伴う形でレプリケーション3台構成のMongoDB(PRIMARY×1台、SECONDARY×2台)の管理が必要となったことから解析作業を依頼された。 -
環境
AWS上のLinuxに構築された上記MongoDBの入った3台のサーバ(本番環境と呼称)を、さらにコピーしてデプロイされた検証環境。
本番環境の設定を持ったままIPアドレスの異なるサーバとしてデプロイされたためレプリケーションがぶっ壊れた。(多分) -
筆者
この作業を依頼された時点でMongoDBの知見は一切ない。
今もあんまりない。
困ったこと
- DB内の情報を検索することができない。
Mongoシェルにてdb.XXX.find
で検索をかけた際に下記のようなエラーメッセージが出力された。
Error: error: {
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotPrimaryNoSecondaryOk"
}
ここから「レプリケーションが壊れてるっぽい」と推測し、調査を開始した。
Mongoシェルにてrs.conf()
を打ったところ、やはり現在のサーバとは異なるIPアドレスがhostとして登録されていた。
- 全サーバが「OTHER」になっており、レプリカセットを編集できない。
「レプリカセットの修正が必要そうだ」というところまではなんとか漕ぎつけたものの、レプリカセットの編集にはPRIMARYの権限が必要であるため修正ができない。
サーバ側のIPアドレスを変えようにもレプリカセットに設定されているIPアドレスは本番環境が保有し稼働し続けていたため奪取できなかった。
やったこと
- 現在のレプリカセットを削除した
レプリカセットの設定を削除するため、本来PRIMARYとなるサーバ(以下Pサーバ)にて/etc/mongod.conf
に記載されていた下記2行をコメントアウト。
replication:
replSetName: "XXX"
さらに一度systemctl restart mongod
コマンドでMongoDBを再起動したのち、mongo
コマンドでmongoシェルを起動しlocalに残っているレプリカセットの設定を削除した。
> use local;
> db.dropDatabase();
ちなみにこのmongoシェル起動の時点でOTHER
の表示が消えていた。
レプリカセットの削除後はexit
でmongoシェルを抜け、再度systemctl restart mongod
コマンドでMongoDBを再起動した。
参考記事
- 今のIPアドレスをレプリカセットとして登録した
Pサーバにて先程修正した/etc/mongod.conf
を再度修正し、追加したコメントアウトを解除した。
その後再度mongoシェルを起動し、下記コマンドでレプリカセットの設定を投入した。
> config = { _id : "example01",members: [{ _id: 0, host: "XXX.XXX.XXX.XXX:27017" },{ _id: 1, host: "XXX.XXX.XXX.YYY:27017" },{ _id: 2, host: "XXX.XXX.XXX.ZZZ:27017" },]}
さらに、ここまでの全ての作業をSECONDARYとなる2台(以下S1サーバ、S2サーバ)にも適用した。
その後、P1サーバのmongoシェルにて下記コマンドを実行し、実行直後からPRIMARY>
やSECONDARY>
の表示がされれば成功。(多分)
> rs.initiate(config)
{ "ok" : 1 }
- 念のためS1・S2サーバのMongoDBを再起動
PサーバをPRIMARYに、S1・S2サーバをSECONDARYとするためにS1・S2サーバそれぞれでsystemctl stop mongod
コマンドを実行し一旦両方のMongoDBが停止している状態にした。
その後、S1サーバ→S2サーバの順にsystemctl start mongod
コマンドでMongoDBを起動させた。
正直この作業は不要だったかもしれない。
余談
systemctl start mongod
コマンドやsystemctl restart mongod
コマンドでMongoDBを起動・再起動させようとした際にエラーが発生し起動できないことがある。
再起動が失敗した際はsystemctl stop mongod
コマンドとsystemctl start mongod
コマンドを順番に実行することで正常に動くことがある。
また、systemctl start mongod
コマンドが動かない場合は/tmp/mongodb-27017.sock
というファイルを削除することで正常に動くようになる。
このファイルはMongoDB起動時に作成され停止時に削除されるため、残ったままの状態だとMongoDBが起動しなくなる。らしい。
mongoシェルの起動時にmongo
コマンドと間違えてmongod
コマンドを実行したりすると作成される。らしい。
最後に
「検証環境だから全然ぶっ壊してもいいんで、ガンガンやっちゃってください」というコメントと共に受け取った環境でのお話のためガンガン行ってます。
一応動き出した後にDB内の検索は上手く行くようになったので多分大丈夫とは思いますが、本当にこれでいいのかな。なんか知らんけど動いてる。こえー。