0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MongoDBの3台構成レプリケーションがぶっ壊れて直した話

Last updated at Posted at 2023-08-17

はじめに

あくまでも「私の環境はこれでどうにかなりました」というお話なので、全ての環境に適用できるものではないと思っております。ご理解ください。
本記事に出てくる用語等に誤りがあったらすみません。

この物語の舞台

  • 背景
    他社で作成されたスマートフォンアプリを移譲されることになり、それに伴う形でレプリケーション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内の検索は上手く行くようになったので多分大丈夫とは思いますが、本当にこれでいいのかな。なんか知らんけど動いてる。こえー。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?