8

レプリカ モードでは、任意の DB 内の任意のコレクションへの各書き込み操作は、oplog コレクションにも書き込みます。

現在、複数の DB に並行して書き込む場合、これらすべての書き込み操作は oplog にも書き込まれます。私の質問: これらの書き込み操作には oplog をロックする必要がありますか? (私は w:1 書き込み懸念を使用しています)。もしそうなら、これは、すべての異なる DB へのすべての書き込み操作の間にグローバル ロックを設定するのと似ていますね。

これについて何かヒントをいただければ幸いです。

4

2 に答える 2

4

ドキュメントによると、レプリケーションでは、MongoDB がプライマリのコレクションに書き込むときに、MongoDB はローカル データベースの特別なコレクションであるプライマリの oplog にも書き込みます。したがって、MongoDB はコレクションのデータベースとローカル データベースの両方をロックする必要があります。mongod は両方のデータベースを同時にロックして、データベースの一貫性を保ち、書き込み操作がレプリケーションを伴う場合でも「オール オア ナッシング」操作であることを保証する必要があります。

これは、プライマリで複数のデータベースに同時に書き込みを行うと、すべての書き込み操作間でグローバル ロックが発生する可能性があることを意味します。MongoDB は書き込みをセカンダリにシリアルに適用せず、代わりに oplog エントリをバッチで収集し、それらのバッチを並行して適用するため、これはセカンダリには適用されません。

于 2015-11-16T22:27:02.260 に答える
3

免責事項これは私の頭の中のすべてですので、間違っていても私を十字架につけないでください. しかし、私を修正してください。

なぜ彼らはすべきですか?

  1. 前提: データベースは定義上、相互接続されていない
  2. oplog エントリは常に冪等です
  3. Oplog はキャップ付きコレクションであり、挿入順序を維持することが保証されています

適用されるクエリの真の並列性を仮定しましょう。そのため、2 つのクエリが同時に到着し、どちらを最初に oplog に挿入するかを決定する必要があります。最初にロックを取得した人が最初に書き込みますよね?以外に、問題があります。最初のクエリは単純なクエリでdb.collection.update({_id:"foo"},{$set:{"bar":"baz"}})、もう 1 つのクエリはより複雑であり、そのため正確性の評価に時間がかかるとします。したがって、それを防ぐために、到着時にロックを取得し、べき等な oplog エントリが書き込まれた後に解放する必要がありました。

ここは自分の記憶に頼るしかない

ただし、クエリは並行して適用されません。クエリはキューに入れられ、到着順に評価されます。データベースは、クエリ オプティマイザーを実行した後、クエリの適用時にロックされます。そのロック中に、べき等 oplog クエリが oplog に書き込まれます。データベースは相互接続されておらず、一度に 1 つのクエリしかデータベースに適用できないため、データベースのロックで十分です。とにかく、2 つのデータ変更クエリを同じデータベースに同時に適用することはできないのに、なぜ oplog にロックを設定する必要があるのでしょうか? どうやら、ローカル データベースがロックされているようです。ただし、データは既にロックされているため、その理由はわかりません。*ひっかく頭*

于 2015-11-16T22:43:42.927 に答える