Mongodb 在两个文档上写入时副本集的最终一致性

Mongodb eventual consistency on replica-sets when writing on two documents

我们有一个客户端连续写入两个文档({w:1})。 例如,原始文档可能是:

{_id: "a", value: 0}, {_id: "b", value: 0}

并且客户端将文档 "a" 更新为 {_id: "a", value: 1},然后在更新完成后,客户端将文档 "b" 更新为 {_id: "b", value: 1}.

第二个客户随后调用 find({})。第二个客户端从一个辅助客户端读取,它可能没有收到所有的更改。 显然它可以读取以下状态:

这是主要的 "real" 个状态(在过去的某个时刻)。

第二个客户端能否看到类似这样的状态:{_id:"a",value:0}{_id:"b",value:1}?请注意,此状态在主服务器上从未存在过。

P.S。 解释 here 说:

Secondaries ... apply write operations in the order that they appear in the oplog.

这是否意味着辅助节点按照在主节点上更新文档的相同顺序更改其文档?

P.S。 find cursors "freeze" 他们正在阅读的文档的状态(即忽略创建游标后所做的更改)?如果我使用 find(...).sort({_id:-1}) 或文档 "a" 的 ID 是 "c"(即大于 "b"),情况会有所不同吗?

谢谢

如果我们的 documnet 在 master 上按顺序更新

  1. 换A
  2. 换B
  3. 换C

然后辅助节点将使用相同的顺序更新文档:

  1. 换A

    documnet can be read without other changes applied

  2. 换B

    documnet can be read without other changes applied

  3. 换C

see this 锁定为 mongo 可以优化操作顺序,即使触发文档更新也可以继续读取。

第一个问题:是的,次要操作的执行顺序与主操作相同。所有操作都记录在oplog中。 oplog 本身不是执行查询的日志(即 updateMany()),而是必须对实际文档执行的操作,因此它的操作变得幂等。

关于游标操作。在游标上迭代时,文档可能会被移动或更新。甚至可能会发生,如果在更新过程中索引或存储位置发生变化,同一个文档会在光标上出现两次。

有一种特殊的snapshot模式可以提供某种隔离,但它有一些限制,即它不能与分片一起使用