对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

写关注

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

注意

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

副本集和分片的集群支持全局默认写关注(write concern)。没有显式写关注(write concern)的操作会继承全局默认。默认的全局写关注(write concern)为“大多数”。有关更多信息,请参阅 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>写关注(write concern):

说明
"majority"

要求确认计算出的大多数有数据投票权的节点已将更改持久写入其本地 oplog。然后,节点在从本地 oplog 读取更改时异步应用这些更改。

副本集中有数据投票权的节点是主节点 members[n].votes 大于 0 的从节点。

如需了解更多信息,请参阅在 { w: "majority" } 写入后读取。

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

示例,考虑一个具有3 个投票成员、主节点-从节点-从节点 (PSS) 的副本集。对于此副本集,计算出的多数为 2,并且写入必须传播到主节点 (primary node in the replica set)和一个从节点(secondary node from replica set)的oplog,以向客户端确认写关注(write concern)。

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

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

如果您为写入指定"majority" 写关注(write concern),并且该操作在返回响应之前没有复制到计算出的多数副本集成员,则数据最终会复制或回滚。请参阅wtimeout

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

<number>

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

w: 1

请求确认写入操作已传播到独立运行的实例mongod 或副本集的主节点 (primary node in the replica set)。如果主节点 (primary node in the replica set)在写入操作复制到任何从节点(secondary node from replica set)之前降级,则可以回滚数据。

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

w: 0

请求不确认写入操作。但是,w: 0 可能会向应用程序返回有关套接字异常和网络错误的信息。如果主节点 (primary node in the replica set)节点在写入操作复制到任何从节点之前降级,则可以回滚数据。

如果您指定w: 0 但包含 j: true,则以 j: true 优先,向独立运行的 或副本集的主节点 (primary node in the mongodreplica set)请求确认。

w 大于 1 需要主节点 (primary node in the replica set)和尽可能多的承载数据的从节点确认,以满足指定的写关注(write concern)。从节点无需成为有投票权成员即可达到写关注(write concern)阈值。

示例,一个 3 节点副本集,具有一个主节点 (primary node in the replica set)和 2 个从节点(secondary node from replica set)。指定 w: 2 需要主节点 (primary node in the replica set)和从从节点(secondary node from replica set)的确认。指定 w: 3 需要主节点 (primary node in the replica set)和两个从节点(secondary node from replica set)的确认。

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

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

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

<custom write concern name>

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

如果自定义写关注(write concern)仅要求主节点 (primary node in the replica set)确认,并且在写入操作复制到任何从节点(secondary node from replica set)之前主节点 (primary node in the replica set)节点会降级,则可以回滚数据。

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

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

j

如果为j: true ,则请求确认 w:<value> 中指定的j: true mongod实例已写入磁盘上日志。单独使用 并不能保证写入不会因副本集主节点 (primary node in the replica set)故障转移转移而回滚。

使用j: true时, MongoDB仅在将请求的节点数(包括主节点 (primary node in the replica set))写入日志后才会返回。 以前,副本集的j: true写关注(write concern)仅要求主节点 (primary node in the replica set)写入日志,而不考虑w: <value>写关注(write concern)。

注意

此选项指定一个时间限制(以毫秒为单位),即在主节点 (primary node in the replica set)上操作成功后,写入操作传播到足够多的节点以实现写关注(write concern)。如果 w 小于或等于 1,则 wtimeout 不应用。如果写入操作在此时限内未达到写关注(write concern), MongoDB将返回写关注(write concern)错误。

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

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

注意

要主节点 (primary node in the replica set)写入操作设立时间限制,请使用maxTimeMS() 方法。

隐式默认写关注(write concern)为w: majorityw: majority 默认要求副本集等待磁盘上日志记录(由 writeConcernMajorityJournalDefault 控制),从而确保写入持久性。但是,包含仲裁节点的副本集部署存在一种边缘情况:

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

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

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

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

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

Non-Arbiters
仲裁节点
投票节点
多数投票节点
隐式默认写关注

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" }

在分片集群上,DDL(数据定义语言)操作运行带有写关注 "majority"。如果您指定了不同的写关注,操作将用 "majority" 覆盖所提供的写关注。

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

独立运行的mongod 会在向内存中应用写入操作或写入磁盘上日志后确认写入操作。下表列出了具有相关写关注(write concern)的独立运行的实例的确认行为:

j 未指定
j:true
j:false

w: 1

inMemory

On-disk journal

inMemory

w: "majority"

磁盘日志(如果与日记一起运行

On-disk journal

inMemory

注意

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

w 值确定在返回成功之前必须确认写入的副本集成员的数量。对于每个符合条件的成员,j 选项确定该成员是在向内存中应用写入操作后还是在写入磁盘上日志后确认写入。

w: "majority"

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

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

j 未指定

确认取决于 writeConcernMajorityJournalDefault 的值:

  • 如果为 true,则确认要求MongoDB通过将写入同步到磁盘上日志来使写入持久性,相当于 j: true

    writeConcernMajorityJournalDefault 默认为 true

  • 如果为 false,则确认要求在内存中进行写入操作,相当于 j: false

j: true

确认要求MongoDB通过将写入同步到磁盘上的日志记录来使写入持久性。

j: false

确认要求在内存中进行写入操作。

通常,如果设立了j: false ,则无需将操作写入磁盘上日志。 但是,如果设置了writeConcernMajorityJournalDefault: true ,则即使设立了j: false ,也需要设立操作写入日志。

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

  • 在将日志刷新到磁盘之前,设立了w: majority的写入不会被确认为完成。

  • w: majority 无论j设置如何,写入操作都会等待"majority"读取快照完成。 这是因为,如果设立了writeConcernMajorityJournalDefault: true ,则多数读取快照基于多数日志写入。

  • 写入操作向客户端应用程序返回并向w: majority确认后,如果设立了majority读关注(read concern),则应用程序可以读取写入结果。

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

w: <number>

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

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

j 未指定

确认需要在内存中执行写入操作,相当于 j: false

j: true

确认要求MongoDB通过将写入同步到磁盘上的日志记录来使写入持久性。

j: false

确认要求在内存中进行写入操作。

注意

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

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

从MongoDB 8.0 开始,大多数承载数据的节点持久写入oplog条目后,{ w: "majority" } 写入会返回确认。然后,节点从本地 oplog 读取更改时会异步应用更改。在早期版本中, MongoDB会等到节点应用写入后再返回确认。

{ w: "majority" }写入确认之后立即对从节点进行查询,可能会在从从节点(secondary node from replica set)应用写入更改之前从集合中读取数据。

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

要读取您自己在主节点 (primary node in the replica set)上的写入,请使用 "majority" 读关注(read concern)和 { w: "majority" }写关注(write concern)。

如果您使用 { w: n } 写关注(write concern),其中 n 大于 计算出的集群节点大多数,并且集群使用默认设置,启用 写关注(write concern)“j”选项 以确认写入日志。"majority"读关注(read concern)只允许读取在副本集的大多数节点上具有持久性的更新。

注意

如果您执行有 { w: n } 写关注(write concern)的写入,且 n 大于计算出的多数,则在没有日志记录且使用默认集群设置的情况下,您可能会在该写入在多数节点上持久性之前收到写入确认。

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

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

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

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

The 本地数据库不支持写关注(write concern)。MongoDB默默地忽略对本地数据库中集合操作的任何配置的写关注(write concern)。

提示

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

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

  • 所有有投票权节点的大多数,包括仲裁节点

  • 所有承载数据的有投票权节点的数量

警告

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

例如,考虑:

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

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

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

    计算出的 majority 为 2,即 2 和 3 中的最小值。该写入操作必须传播到主节点和某一从节点,以向客户端确认写关注 "majority"

  • 具有 3 个投票节点、主节点-从节点-仲裁节点 (PSA) 的副本集:

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

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

    计算出的多数为 2,是 2 和 2 中的最小值。由于写入只能应用于数据承载成员,因此写入必须传播到主节点 (primary node in the replica set)和从从节点(secondary node from replica set),以向客户端确认写关注(write concern)"majority"

    提示

    避免将 "majority" 写关注(write concern)与 PSA 或其他要求所有数据承载投票节点均可用于确认写入的拓扑结构一起使用。为了ACID 一致性保证"majority"写关注(write concern)的持久性,部署不要求所有数据承载投票节点都可用的拓扑结构,例如 PSS。

警告

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

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

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

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

来源
说明

clientSupplied

应用程序中指定了写关注。

customDefault

写入关注源自自定义的默认值。请参阅 setDefaultRWConcern

getLastErrorDefaults

写关注源自副本集的 settings.getLastErrorDefaults 字段。

implicitDefault

在没有所有其他写入关注规范的情况下,写入关注源自服务器。

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

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

  • 写入操作使用写关注。

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

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

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

在 版本中进行了更改。提交法定人数在主节点8.0 (primary node in the replica set)提交索引构建之前必须准备好多少个节点才能完成索引构建。相反,当主节点 (primary node in the replica set)已提交索引构建时,写关注(write concern)在命令返回成功 .. 之前有多少个节点必须复制索引构建oplog条目:

在以前的版本中,当主节点提交索引构建时,写关注会指定在此命令返回成功之前有多少个节点必须完成索引构建。