“文档” 菜单
文档首页
/
MongoDB Manual
/

写关注

在此页面上

  • 写关注说明
  • 隐式默认写关注
  • 确认行为
  • 更多信息

写关注描述了从 MongoDB 请求的对独立 mongod副本集分片集群的写入操作的确认级别。在分片集群中, mongos实例会将写关注传递给分片。

注意

对于多文档事务,您可以在事务级别而非单个操作级别设置写关注。请勿为事务中的写入操作显示设置写关注。

如果您为多文档事务指定 "majority" 写关注,并且该事务无法复制到计算出的大多数副本集成员,则该事务可能不会立即在副本集成员上回滚。副本集最终将保持一致。事务始终在所有副本集成员上应用或回滚。

副本集和分片集群支持设置全局默认的写关注。未指定显式写关注的操作会继承全局默认写关注设置。有关详细信息,请参阅 setDefaultRWConcern

要了解有关为 MongoDB Atlas 中托管的部署设置写关注的更多信息,请参阅使用 MongoDB Atlas 构建弹性应用程序

写关注可包括以下字段:

{ w: <value>, j: <boolean>, wtimeout: <number> }
  • w 选项会请求确认写入操作已传播到指定数量的 mongod 实例或带有指定标签的 mongod 实例。

  • j 选项以请求确认写入操作已写入磁盘上日志,且

  • wtimeout 选项用于指定时间限制,以防止写入操作无限期阻塞。

w 选项会请求确认写入操作已传播到指定数量的 mongod 实例或带有指定标记的 mongod 实例。如果写关注缺少 w 字段,MongoDB 则会将 w 选项设为默认写关注。

注意

如果使用 setDefaultRWConcern 来设置默认写关注,则须指定 w 字段值。

通过使用 w 选项,可使用以下 w: <value> 写关注:

说明
"majority"

请求确认写入操作已持久提交给计算出的大多数承载数据的有投票权成员(即members[n].votes 大于 0 的主节点和从节点)。{ w: "majority" }大多数 MongoDB 部署的默认写关注。请参阅隐式默认写关注

例如,考虑一个具有 3 个投票权节点的副本集,即主节点-从节点-从节点 (P-S-S)。对于此副本集,计算出的 majority 为 2,并且写入必须传播到主节点和从节点,以便向客户端确认写关注。

注意

members[n].votes 大于 0已隐藏已延迟优先级为 0 的节点可确认 "majority" 写入操作。

延迟的从节点在所配置的 secondaryDelaySecs 之前无法返回写入确认。

当写入操作使用 w: "majority" 确认返回给客户端后,客户端可使用 "majority" readConcern 来读取该写入操作的结果。

如果为多文档事务指定 "majority" 写关注,并且该事务未能复制到计算出的多数副本集成员,则该事务可能不会立即在副本集成员上回滚。副本集最终将保持一致。事务始终在所有副本集成员上应用或回滚。

请参阅确认行为以了解 mongod 实例何时会确认该写入操作。

<number>

要求确认写入操作已传播到指定数量的 mongod 实例。例如:

w: 1

要求确认写入操作已传播到独立 mongod 或副本集中的主节点。如果主节点在写入操作复制到任一从节点之前退出,则可回滚数据。

警告

如果写入操作使用了 { w: 1 } 写关注,则当主节点在写入操作完成之前重新启动时,回滚目录可能会排除在 oplog hole 操作之后提交的写入操作。

w: 0

要求不确认写入操作。但是,w: 0 可能会向应用程序返回有关套接字异常和网络错误的信息。如果主节点在写入操作复制到任一从节点之前退出,则可回滚数据。

如果您指定了 w: 0 但包含 j: truej: true 则可优先要求独立 mongod 或副本集主节点进行确认。

w 可要求主节点以及所需尽可能多的承载数据的从节点进行确认,从而满足指定的写关注。从节点不需要成为投票成员即可达到写关注阈值。

例如,有一 3 成员副本集,其中包含 1 个主节点和 2 个从节点。指定 w: 2 时要求主节点和某一从节点进行确认。指定 w: 3 时要求主节点和两个从节点均进行确认。

注意

已隐藏已延迟优先级为 0 的节点可确认 w: <number> 写入操作。

延迟的从节点在所配置的 secondaryDelaySecs 之前无法返回写入确认。

请参阅确认行为以了解 mongod 实例何时会确认该写入操作。

<custom write concern name>

要求确认写入操作已传播到满足 settings.getLastErrorModes 中所定义自定义写关注的 tagged 成员。有关示例,请参阅自定义多数据中心写关注

如果自定义写关注仅要求主节点进行确认,且在将写入操作复制到任一从节点之前主节点便已退出,则可回滚数据。

请参阅确认行为以了解 mongod 实例何时会确认该写入操作。

提示

另请参阅:

j 选项会要求 MongoDB 确认写入操作已写入磁盘日志

j

如果为 j: true ,则要求确认已将 mongod 实例(如 w:<value> 中所指定)写入磁盘上日志。j: true 自身并不保证写入操作不会因副本集主节点故障转移而进行回滚。

3.2 版本中的更改:设置 j: true,MongoDB 仅会在已将包括主节点在内的所请求节点数写入日志后才会返回。以前,副本集中的 j: true 写关注仅要求主节点写入日志,而不考虑 w: <值>写关注。

注意

此选项指定写关注的时间限制(以毫秒为单位)。wtimeout 只适用于w 值大于 1 的情况。

wtimeout 即使所需写关注最终会成功,也会导致写入操作在达到指定限制后返回一个错误。当这些写入操作返回时,MongoDB不会撤消在写关注超过 wtimeout 时间限制之前已执行的成功数据修改。

如果未指定 wtimeout 选项且写关注的级别无法实现,写入操作则会无限期阻塞。将 wtimeout 值指定为 0 等同于不带 wtimeout 选项的写关注。

从 MongoDB 5.0 开始,隐式默认写关注w: majority。然而,针对包含仲裁节点的部署则有特殊考虑:

  • 副本集的投票多数是 1 加投票成员数量的一半,四舍五入。如果数据承载投票成员的数量不超过投票多数,则默认写关注为 { w: 1 }

  • 在所有其他场景中,默认写关注为 { w: "majority" }

具体来说,MongoDB 使用以下公式来确定默认写关注:

if [ (#arbiters > 0) AND (#non-arbiters <= majority(#voting-nodes)) ]
defaultWriteConcern = { w: 1 }
else
defaultWriteConcern = { w: "majority" }

例如,考虑以下部署以及各自的默认写关注:

非仲裁节点
仲裁节点
投票节点
多数投票节点
隐式默认写关注
2
1
3
2
{ w: 1 }
4
1
5
3
{ w: "majority" }
  • 在第一个示例中:

    • 有 2 个非仲裁节点和 1 个仲裁节点,共有 3 个投票节点。

    • 多数投票节点(1 加 3 的一半,四舍五入)为 2。

    • 非仲裁节点的数量 (2) 等于多数投票节点 (2),导致隐式写关注为 { w: 1 }

  • 在第二个示例中:

    • 共有 5 个投票节点,其中有 4 个非仲裁节点和 1 个仲裁节点。

    • 多数投票节点(1 加 5 的一半,四舍五入)为 3。

    • 非仲裁节点的数量 (4) 大于多数投票节点 (3),导致隐式写关注为 { w: "majority" }

w 选项和 j 选项决定 mongod 实例确认写入操作的时间。

独立 mongod 在向内存中应用写入操作后或在写入磁盘上日志后,会确认该写入操作。下表列出独立实例的确认行为以及相关的写关注:

j 未指定
j:true
j:false
w: 1
inMemory
磁盘上日志
inMemory
w: "majority"
磁盘日志(如果与日记一起运行
磁盘上日志
inMemory

注意

writeConcernMajorityJournalDefault 设为 false 时,MongoDB 不会等待 w: "majority" 写入磁盘日志后才确认写入操作。因此,"majority" 写入操作可能会在给定副本集中的大多数节点出现短暂丢失时(例如,崩溃和重启时)进行回滚。

指定给 w 的值决定了在返回成功之前必须确认写入的副本集成员数。对于每个有资格的副本集成员,j 选项决定了该成员引在向内存应用写入操作之后还是写入磁盘上日志之后确认写入操作。

w: "majority"

副本集的任一承载数据的有投票权成员均可参与对 "majority" 写入操作进行写入确认。

下表列出了该成员何时可根据 j 值来确认写入操作:

j 未指定

确认取决于 writeConcernMajorityJournalDefault 的值:

  • 如果为 true,则确认时要求对磁盘上日志 (j: true) 进行写入操作。

    writeConcernMajorityJournalDefault 默认为 true

  • 如果为 false,则确认需要在内存中进行写入操作(j: false)。

j: true
确认时要求对磁盘上日志进行写入操作。
j: false
确认要求在内存中进行写入操作。

注意

有关行为详情,请参阅 w: "majority" 行为

w: <number>

副本集的任一承载数据的成员均可参与 w: <数量> 写入操作的写入确认。

下表列出了该成员何时可根据 j 值来确认写入操作:

j 未指定
确认要求在内存中进行写入操作 (j: false)。
j: true
确认时要求对磁盘上日志进行写入操作。
j: false
确认要求在内存中进行写入操作。

注意

已隐藏已延迟优先级为 0 的节点可确认 w: <number> 写入操作。

延迟的从节点在所配置的 secondaryDelaySecs 之前无法返回写入确认。

使用因果一致的客户端会话时,只有在以下情况下,客户端会话才能保证因果一致性:

  • 关联的读取操作使用 "majority" 读关注,而

  • 关联的写入操作使用 "majority" 写关注。

有关详细信息,请参阅因果一致性

本地数据库不支持写关注。MongoDB 会静默忽略为针对本地数据库中集合的操作所配置的全部写关注。

提示

rs.status() 返回 writeMajorityCount 字段,其中包含计算出的多数性数量。

写关注的多数 "majority" 会按以下值中较小的值来计算:

  • 所有有投票权成员(包括仲裁节点)的 majority 与

  • 所有承载数据的有投票权成员的数量。

警告

如果计算出的 majority 数值等于所有承载数据的投票节点(例如有 3-节点的“主节点-从节点-仲裁节点”部署),写关注 "majority" 可能会超时,或在承载数据的投票节点关闭或无法访问时永不进行确认。如果可能,请使用承载数据的投票节点而不是仲裁节点。

例如,考虑:

  • 具有 3 个投票成员的副本集,即主节点-从节点-从节点 (P-S-S):

    • 所有有投票权成员的 majority 为 2。

    • 所有承载数据的有投票权成员的数量为 3。

    计算出的 majority 为 2,即 2 和 3 中的最小值。该写入操作必须传播到主节点和某一从节点,以向客户端确认写关注 "majority"
  • 具有 3 个有投票权成员(即,主节点-从节点-仲裁节点 (P-S-A))的副本集

    • 所有有投票权成员的 majority 为 2。

    • 所有承载数据的投票成员的数量为 2。

    计算出的 majority 为 2,即 2 和 2 中的最小值。由于写入只能应用于承载数据节点,因此写入必须传播到主节点和从节点,以确认对客户端的写关注 "majority"

    提示

    避免将 "majority" 写关注与 (P-S-A) 或其他要求所有数据承载投票成员都可用来确认写入的拓扑一起使用。希望使用 "majority" 写关注实现持久性保证的客户应改为部署不要求所有数据承载投票成员都可用的拓扑(例如P-S-S)。

警告

要将仲裁节点添加到现有副本集:

在使用具有一个仲裁节点的新副本集之前,您不需要更改集群范围的写关注(write concern)。

从 4.4 版本开始,MongoDB 会跟踪写关注 provenance,而后者表示特定写关注的来源。您可能会在 getLastError 指标中看到 provenance、写关注错误对象和 MongoDB 日志。

下表显示了可能的写关注 provenance 值及其重要性:

来源
说明
clientSupplied
应用程序中指定了写关注。
customDefault
写入关注源自自定义的默认值。请参阅 setDefaultRWConcern
getLastErrorDefaults
写关注源自副本集的 settings.getLastErrorDefaults 字段。
implicitDefault
在没有所有其他写入关注规范的情况下,写入关注源自服务器。

提交法定人数写关注之间有重要区别:

  • 索引构建使用提交法定人数

  • 写入操作使用写关注

集群中的每个承载数据的节点均为一个有投票权成员。

提交法定人数指定了必须准备多少个承载数据的有投票权成员或是哪些有投票权成员(包括主节点)来提交同步索引构建。主节点才会执行提交。

写关注是指确认写入操作已传播到指定数量的实例的级别。

提交法定人数指定了在主节点提交索引构建之前必须有多少个节点准备好完成索引构建。相反,当主节点已提交索引构建时,写关注则指定了在此命令返回之前有多少个节点必须完成索引构建。

← 读关注 (read concern)