Docs 菜单

Docs 主页开发应用程序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个投票成员、主节点-从节点-从节点 (PSS) 的副本集。对于此副本集,计算出的多数为 2,并且写入必须传播到主节点和一个从节点,以向客户端确认写关注。

注意

0members[n].votes大于0 的 隐藏 、"majority" 延迟 和 优先级 成员可以确认 写入操作。

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

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

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

mongod有关 实例何时确认写入,请参阅 确认行为 。

<number>

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

w: 1

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

警告

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

w: 0

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

如果您指定w: 0但包含j: true ,则j: 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 与

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

警告

如果计算出的多数数等于所有承载数据的有投票权成员的数量(例如使用3成员主节点-从节点-仲裁节点部署),则在以下情况下,写关注"majority"可能会超时或永远不会得到确认:承载数据的有投票权成员已关闭或无法访问。如果可能,请使用承载数据的有投票权成员而不是仲裁节点。

例如,考虑:

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

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

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

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

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

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

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

    提示

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

警告

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

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

MongoDB 跟踪写关注provenance ,它指示特定写关注的来源。您可能会看到 { getLastError指标、写关注错误对象和 MongoDB 日志中显示provenance

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

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

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

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

  • 写入操作使用写关注

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

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

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

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

← 读关注 (read concern) "snapshot"