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が始まり、完了すると再びセカンダリノードとして復旧できます。