[mongodb]レプリケーション成功していても同期元と同期先でDBの状態が同じでない場合が存在する

[mongodb]レプリケーション成功していても同期元と同期先でDBの状態が同じでない場合が存在する事象に
遭遇したのでブログにします。

1.基礎知識
mongodbのレプリケーションはPRIMARY側のDB操作記録をoplogという更新ログに記録し、SECONDARY側が自身のoplogよりも
新しいoplogの差分をPRIMARY側に要求して、oplogをコピーし、差分のDB操作をSECONDARY側で実施することで実現しています。
oplogはレプリカセットが構成されている時のみ記録されます。

2.前提
テスト環境で3台構成でレプリカセットを組んでいるうちの2台(SECONDARY,ARBITAR)を運用コスト削減の為に通常はシャットダウン。
PRIMARYをレプリカセットを解除してスタンドアローンで通常運用。
月次のWindowsパッチ当ての時のみ3台構成のレプリカセットに戻し、同期させ、作業終了後にレプリカセットを解除して2台を元通りに
シャットダウンという運用をしていました。

3.事象
レプリケーション自体は成功していますが、スタンドアローン運用時の操作は更新ログのoplogに記録されないので、
同期元と同期先でDBの内容に不一致があるのではないかと疑い、同期元と同期先でコレクションの件数を比較してみました。

4.同期元、同期先でのコレクション件数の比較結果
コレクション件数不一致が確認されました。
スタンドアローン運用中の更新操作は上記運用では反映されない事がわかりました。

csRS:PRIMARY> use Collection1
csRS:PRIMARY> db.getCollectionNames().forEach(function(v){print(v , db.getCollection(v).count());});
AutomationRanges 0
AutomationStates 0
ClassificationsMap 236
Contacts 236
Devices 234
HistoryRanges 0
HistoryTasks 2
Interactions 1509
KeyBehaviorCache 236
Locations 1
OperationStatuses 3
Outcomes 0
UserAgents 50
csRS:PRIMARY>

csRS:SECONDARY> use Collection1
csRS:SECONDARY> db.getCollectionNames().forEach(function(v){print(v , db.getCollection(v).count());});
ection(v).count());});
AutomationRanges 0
AutomationStates 0
ClassificationsMap 236
Contacts 236
Devices 234
HistoryRanges 0
HistoryTasks 2
Interactions 1503
KeyBehaviorCache 236
Locations 1
OperationStatuses 3
Outcomes 0
UserAgents 49
csRS:SECONDARY>

5.解決方法
同期再開の都度、再同期(SECONDARYのdatapathディレクトリを空にしてmongodbサービスを再起動)
を行う手順を追加する。

レプリケーション成功していても同期元と同期先でDBの状態が同じでない場合が存在するという事が
わかりました。

Comments are closed.