2

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

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

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

第二个客户find({})随后打电话。第二个客户端从辅助客户端读取,可能尚未收到所有更改。显然它可以读取以下状态:

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

这是主要的“真实”状态(在过去的某个时刻)。

第二个客户可以看到如下状态:{_id:"a",value:0}, {_id:"b",value:1}? 请注意,此状态在主节点上从未存在过。

PS这里的解释说:

辅助节点...按照它们在 oplog 中出现的顺序应用写操作。

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

PSfind游标是否“冻结”了它们正在阅读的文档的状态(即忽略创建游标后所做的更改)?如果我使用find(...).sort({_id:-1})或者如果文档“a”的 id 是“c”(即大于“b”),情况会有所不同吗?

谢谢

4

2 回答 2

1

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

关于光标操作。在遍历光标时可能会发生文档移动或更新的情况。如果索引或存储位置在更新期间发生更改,甚至可能发生相同的文档在光标上出现两次。

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

于 2016-05-30T11:58:51.050 回答
0

如果我们的文档网络是由 master 上的序列更新的

  1. 改变一个
  2. 改变 B
  3. 改变 C

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

  1. 改变一个

    无需应用其他更改即可读取文档网

  2. 改变 B

    无需应用其他更改即可读取文档网

  3. 改变 C

对于锁定,请参阅此,因为 mongo 可以优化操作顺序,即使触发文档更新继续进行也可以允许读取。

于 2016-05-30T11:45:02.543 回答