読者です 読者をやめる 読者になる 読者になる

kakts-log

programming について調べたことを整理していきます

mongod replicaSet セカンダリノードを起動後に[RS102 too stale to catch up]が出たときの対処法

mongoでレプリカセットを組んでいて、たまに障害でセカンダリノードのサーバなどが死んで、
セカンダリノードのmongodプロセスを起動した後に、プライマリのデータをsyncできずに下記のエラーが出る場合があります

[rsBackgroundSync] replSet error RS102 too stale to catchup, at least from....

このエラーは、セカンダリノードが数時間とか長い間死んだ状態になっていて、syncの状態がstale(古い)な状態で再起動した場合に発生します。

原因

原因としては、セカンダリノードのoplogの情報が古すぎてsyncできないことが挙げられます。
mongoの仕組みとして、プライマリノードにデータが書き込まれるときのオペレーション情報をoplogに保持しています。
oplogコレクションは capped size collectionのため、一定サイズを超えた場合に古いものから消されていきます。 セカンダリノードはこのプライマリノードのoplogをtailしてsyncを行うのですが、 セカンダリノードが死んだままだと、
syncに必要なoplogの状態が更新されずに、プライマリのデータとsyncさせるためのデータが欠損してしまうために、このエラーが出ます。

対策

対策としては、セカンダリノードで持っているデータは古すぎて使えないため、一回まっさらな状態にした後にmongodを起動させると、初期状態からsyncが始まり、復旧できます

  • 問題が起きたセカンダリノードのmongodプロセスを停止する
  • セカンダリノードのデータディレクトリ(/data/mongodb とか、設定していたデータディレクトリ)を削除する。
  • 再度mongodをリセットする

これで再度初期状態からsyncが始まり、完了すると再びセカンダリノードとして復旧できます。

参考

stackoverflow.com