8

在副本模式下,对任何 DB 中的任何集合的每个写入操作,也会写入 oplog 集合。

现在,当并行写入多个 DB 时,所有这些写入操作也会写入 oplog。我的问题:这些写操作需要锁定 oplog 吗?(我正在使用 w:1 写关注)。如果他们这样做了,这有点类似于在所有不同数据库的所有写操作之间有一个全局锁,不是吗?

我很乐意得到这方面的任何提示。

4

2 回答 2

4

根据文档,在复制中,当 MongoDB 写入主节点上的集合时,MongoDB 也会写入主节点的 oplog,这是本地数据库中的一个特殊集合。因此,MongoDB 必须同时锁定集合的数据库和本地数据库。mongod 必须同时锁定两个数据库以保持数据库一致并确保写入操作,即使是复制,也是“全有或全无”操作。

这意味着在主数据库上并行写入多个数据库可能会导致所有写入操作之间的全局锁定。这不适用于辅助节点,因为 MongoDB 不会将写入串行应用到辅助节点,而是批量收集 oplog 条目,然后并行应用这些批处理。

于 2015-11-16T22:27:02.260 回答
3

免责声明这是我头脑中的全部内容,所以如果我有错误,请不要将我钉在十字架上。但是,请纠正我。

他们为什么要这样做?

  1. 前提:根据定义,数据库不是相互连接的
  2. oplog 条目总是幂等的
  3. Oplog 是一个有上限的集合,保证保留插入顺序

让我们假设正在应用的查询的真正并行性。因此,我们有两个查询同时到达,我们需要先决定将哪个查询插入到 oplog 中。第一个拿到锁的会先写,对吧?除了,有问题。让我们假设第一个查询是一个简单db.collection.update({_id:"foo"},{$set:{"bar":"baz"}})的查询,而另一个查询更复杂,因此需要更长的时间来评估正确性。因此,为了防止这种情况发生,必须在到达时获取锁,并在写入幂等 oplog 条目后释放。

这是我必须依靠我的记忆的地方

但是,查询不会并行应用。查询按到达顺序排队和评估。数据库在通过查询优化器运行后被锁定在查询的应用程序上。在该锁定期间,幂等 oplog 查询被写入 oplog。由于数据库没有相互连接,并且在任何给定时间只能将一个查询应用于数据库,因此数据库上的锁定就足够了。无论如何,没有两个数据更改查询可以同时应用于同一个数据库,那么为什么要在 oplog 上设置一个锁呢? 显然,对本地数据库进行了锁定。但是,由于已经对数据进行了锁定,因此我看不出原因。*抓挠我的头*

于 2015-11-16T22:43:42.927 回答