文档菜单
文档首页
/
MongoDB 手册
/

写入关注

本页内容

  • 写入关注规范
  • 隐式默认写入关注
  • 确认行为
  • 更多信息

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

注意

对于多文档事务,您在事务级别设置写入关注度,而不是在单个操作级别。不要在事务中对单个写入操作显式设置写入关注度。

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

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

有关在MongoDB Atlas上托管部署的写入关注度设置的信息,请参阅使用MongoDB Atlas构建弹性应用程序

写入关注度可以包含以下字段

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

  • 请求写入操作已写入磁盘日志的j选项。

  • 使用 wtimesout 选项来指定一个时间限制,以防止写操作无限期地阻塞。

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

注意

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

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

描述
"majority"

请求确认计算出的数据承载投票成员的大多数已将更改持久地写入其本地的 多数 操作日志。然后,成员将异步地将更改应用于它们从本地操作日志中读取时。

已更改版本8.0: MongoDB 在确认写操作之前不会等待成员应用更改,这与之前的版本不同。

副本集的数据承载投票成员包括主节点和任何具有members[n].votes大于0辅助节点

有关更多信息,请参阅在写入{ w: "majority" }之后读取。

{ w: "majority" }是大多数MongoDB部署的默认写入关注点。请参阅隐式默认写入关注点。

例如,考虑一个由3个投票成员组成的副本集,即主-辅助-辅助(P-S-S)。对于这个副本集,计算出的多数是两个,写入必须传播到主节点和一个辅助节点的操作日志中,以向客户端确认写入关注点。

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

延迟的辅助节点最早可以在配置的secondaryDelaySecs之后返回写入确认。

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

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

有关何时mongod实例确认写入的详细信息,请参阅确认行为

<number>

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

写: 1

请求确认写操作已传播到独立 mongod 或复制集的主节点。如果主节点在写操作复制到任何副节点之前下线,则数据可能会被 回滚

警告:如果写操作使用 { w: 1 } 写关注,如果主节点在写操作完成之前重启,回滚目录可能排除在 oplog 空洞 之后提交的写操作。

写: 0

请求不确认写操作。但是,写: 0 可能会向应用程序返回有关套接字异常和网络错误的详细信息。如果主节点在写操作复制到任何副节点之前下线,则数据可能会被 回滚

如果您指定 写: 0 但包括 j: true,则 j: true 优先请求确认来自独立 mongod 或复制集的主节点。

大于 1 的 需要来自主节点以及满足指定写关注所需的数据承载副节点的确认。副节点不需要是投票成员即可满足写关注阈值。

例如,考虑一个有主节点和 2 个副节点的 3 成员复制集。指定 写: 2 需要来自主节点和一个副节点的确认。指定 写: 3 需要来自主节点和两个副节点的确认。

隐藏延迟优先级 0成员可以确认 w: <number> 写操作。

延迟的辅助节点最早可以在配置的secondaryDelaySecs之后返回写入确认。

有关何时mongod实例确认写入的详细信息,请参阅确认行为

<自定义写关注名称>

请求确认写操作已传播到满足在 标记 成员,这些成员符合在 settings.getLastErrorModes 中定义的自定义写关注。例如,请参阅 自定义多数据中心写关注。

如果自定义写关注仅要求从主节点获得确认,并且在写操作复制到任何从节点之前主节点已降级,则可以回滚数据。

有关何时mongod实例确认写入的详细信息,请参阅确认行为

提示

另请参阅

j 选项请求MongoDB确认写操作已写入到磁盘日志。

j

如果 j: true,则请求确认指定的 mongod 实例(在 w: <value> 中指定)已将数据写入磁盘日志。仅 j: true 并不能保证写入不会因为副本集主节点故障转移而回滚。

使用 j: true,MongoDB 只在请求的成员数量(包括主节点)都已写入日志后返回。之前在副本集中使用 j: true 写入关注时,只要求主节点写入日志,而不考虑 w: <value> 写入关注。

注意

此选项指定写入关注的超时时间,以毫秒为单位。只有当w值大于1时,wtimeout才适用。

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

如果您未指定wtimeout选项,并且写入关注级别不可达到,则写入操作将无限期阻塞。指定0wtimeout值等同于没有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 }

  • 在第二个例子中

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

    • 投票节点的多数(1加上5的一半,向下取整)为3。

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

选项 w 和选项 j 决定了何时 mongod 实例确认写操作。

独立的 mongod 实例在将写操作应用在内存中或写入磁盘日志后确认写操作。以下表格列出了独立模式和相关的写关注行为

j 选项未指定
j:true
j:false
写: 1
内存中
磁盘日志中
内存中
w: "majority"
磁盘日志(如果启用日志记录)
磁盘日志中
内存中

注意

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

确认需要写入到内存。

通常,如果设置 j: false,则不需要将操作写入磁盘日志。然而,如果设置 writeConcernMajorityJournalDefault: true,即使设置 j: false,也必须将操作写入日志。

如果设置 j: falsewriteConcernMajorityJournalDefault: true,则写入操作异步写入日志。

  • 设置 w: majority 的写入操作在日志刷新到磁盘之前不会被视为已完全确认。

  • w: 大多数 写入操作等待完成 "majority" 读取快照,无论 j 设置如何。这是因为如果设置了 writeConcernMajorityJournalDefault: true,则大多数读取快照基于已记录的大多数写入。

  • 在写入操作向客户端应用程序返回 w: 大多数 确认后,如果设置了 majority 读取关注点,则应用程序可以读取写入的结果。

有关行为细节,请参阅 w: "majority" 行为。

w: <number>

副本集中的任何承载数据的成员都可以参与 w: <number> 写入操作的确认。

以下表格列出了根据 j 值成员可以确认写入的时间。

j 选项未指定
确认需要在内存中写入操作(j: false)。
j: true
确认需要写入到磁盘日志。
j: false
确认需要写入到内存。

注意

隐藏延迟优先级 0成员可以确认 w: <number> 写操作。

延迟的辅助节点最早可以在配置的secondaryDelaySecs之后返回写入确认。

从 MongoDB 8.0 开始,{ w: "majority" } 写入操作在大多数承载数据的成员持久化写入 oplog 条目后返回确认。然后,成员异步地应用它们从本地 oplog 读取的更改。在早期版本中,MongoDB 等待成员应用写入后返回确认。

{ w: "majority" } 写入操作返回确认后立即对次级进行查询可能从次级在应用写入更改之前读取的集合中读取。

如果您的应用程序从次级读取并需要立即访问在 { w: "majority" } 写入中做出的更改,请在 因果一致性 会话中运行这些操作。

因果一致性客户端会话中,只有当

  • 相关的读取操作使用"majority"读取关注度,并且

  • 相关的写入操作使用"majority"写入关注度时,客户端会话才保证因果一致性。

详细信息请参阅因果一致性。

本地数据库local database不支持写关注。MongoDB会静默忽略本地数据库集合操作上配置的任何写关注。

提示

rs.status()返回包含计算出的多数数字的字段writeMajorityCount

写关注多数"majority"的计算为以下值中的较小值

  • 所有投票成员(包括仲裁员)的多数 vs.

  • 所有data-bearing投票成员的数量。

警告

在计算出的多数数字等于所有data-bearing投票成员的数量(例如,在3成员主-次-仲裁员部署中)的情况下,如果数据投票成员出现故障或不可达,写关注多数"majority"可能会超时或不会被确认。如果可能,请使用数据投票成员而不是仲裁员。

例如,考虑以下情况

  • 一个有3个投票成员的副本集,主-次-次(P-S-S)

    • 所有投票成员的多数是2。

    • 所有数据投票成员的数量是3。

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

    • 所有投票成员的多数是2。

    • 所有数据投票成员的数量是2。

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

    提示

    避免在(P-S-A)或其他需要所有承载数据投票成员都可用以确认写入的拓扑中使用"majority"写入关注。希望使用"majority"写入关注以获得持久性保证的客户应部署不需要所有承载数据投票成员都可用的拓扑(例如P-S-S)。

警告

避免在一个副本集中部署多个仲裁者。参见多个仲裁者的注意事项

要将仲裁者添加到现有的副本集

  • 通常,如果副本集中有两个或更少的承载数据成员,您可能需要首先设置副本集的集群范围写入关注

  • 有关为什么您可能需要设置集群范围写入关注的信息,请参阅集群范围写入关注

在启动带有仲裁者的新副本集之前,您不需要更改集群范围的写入关注。

提示

另请参阅

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

以下表格显示了可能的写入关注来源值及其含义

来源
描述
clientSupplied
写入关注是在应用程序中指定的。
customDefault
写入关注是从自定义定义的默认值中起源的。参见setDefaultRWConcern
getLastErrorDefaults
写入关注是从副本集的settings.getLastErrorDefaults字段中起源的。
implicitDefault
在没有其他写入关注规范的情况下,写入关注是从服务器中起源的。

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

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

  • 写入操作使用写入关注。

集群中每个承载数据的节点都是一个投票成员。

提交法定人数指定在主节点执行提交之前,需要多少个承载数据的投票成员,或者哪些投票成员(包括主节点)必须准备好提交一个同时索引构建

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

已更改版本8.0: 提交法定人数指定在主节点提交索引构建之前,需要多少个节点准备好完成索引构建。相比之下,当主节点提交索引构建时,写入关注指定在命令返回成功之前,需要多少个节点复制索引构建的操作日志条目。

在之前的版本中,当主节点提交索引构建时,写入关注指定在命令返回成功之前,需要多少个节点完成索引构建。

返回

"快照"