Docs 菜单
Docs 主页
/
MongoDB Manual
/

读关注 (read concern)

在此页面上

  • 读关注级别
  • readConcern 支持
  • Considerations

借助 readConcern 选项,您可以控制从副本集分片集群读取的数据的一致性和隔离属性。

通过有效使用写关注和读关注,您可以适当调整一致性和可用性保证的级别,例如等待更强的一致性保证,或者放松一致性要求以提供更高的可用性。

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

以下是可用的读关注级别:

level
说明

查询从实例返回数据,不保证数据已写入副本集的多数成员(即,可能会回滚)。

针对主节点和从节点默认读取。

可用性:无论有没有因果一致的会话和事务,均可使用读关注 "local"

更多信息,请参阅 "local" 参考页。

查询从实例返回数据,不保证数据已写入副本集的多数成员(即,可能会回滚)。

可用性:因果一致的会话和事务不可使用读关注 "available"

对于分片集群,"available" 读关注在各种读关注中提供最低延迟读取。但这会牺牲一致性,因为 "available" 读取分片集合时可能会返回孤立文档。为了避免读取分片集合时返回孤立文档,请使用其他读关注,例如 "local"

更多信息,请参阅 "available" 参考页。

该查询返回已被副本集多数成员确认的数据。即使失败,读取操作返回的文档也是持久性的。

为了保证读关注“多数”,副本集成员在多数提交点从其内存数据视图返回数据。因此,读关注 "majority" 的性价比与其他读关注相当。

可用性:

无论有没有因果一致的会话和事务,均可使用读关注 "majority"

要求:要使用读关注级别 "majority",副本集必须使用 WiredTiger 存储引擎

对于多文档事务中的操作,仅当事务以写关注“多数”提交时,读关注 "majority" 才提供保证。否则,"majority" 读关注无法保证事务中读取的数据。

更多信息,请参阅 "majority" 参考页。

该查询返回的数据反映了在读取操作开始之前完成的所有成功的多数已确认的写入操作。该查询可能会等待并发执行的写入操作的数据复制到多数副本集成员之后,再返回结果。

如果多数副本集成员在读操作后崩溃并重新启动,且 writeConcernMajorityJournalDefault 设置为默认状态 true,则读操作返回的文档是持久化的。

writeConcernMajorityJournalDefault 设置为 false 时,MongoDB 不会等待 w: "majority" 写入在写入到磁盘日志后才确认写入。例如,"majority" 写操作可能会在给定副本集中的大部分节点发生临时断连(例如崩溃和重启)的情况下回滚。

可用性:
  • 读关注"linearizable"不可用于因果一致的会话和事务。

  • 您只能为primary上的读取操作指定线性化读关注。

您不能将 $out$merge 阶段与读关注 "linearizable" 一起使用。换言之,如果将 "linearizable" 读关注为 db.collection.aggregate() 指定,则不能在管道中包含任一阶段。

要求:

仅当读操作指定唯一标识单个文档的查询过滤时,才应用线性化读关注(read concern)ACID 一致性保证。此外,如果不满足以下条件,则线性化读关注(read concern)可能无法从一致的快照中读取,从而导致未返回与过滤匹配的文档:

  • 该查询使用不可变字段作为查询的搜索键。示例,在_id字段中搜索或使用$natural

  • 并发更新不会改变查询的搜索键。

  • 搜索键具有唯一索引,并且查询使用该索引。

如果满足前面的任何条件,查询将从一致的快照中读取以返回单个匹配的文档。

始终将maxTimeMS与线性化读关注一起使用,以防大多数数据承载成员不可用。maxTimeMS确保操作不会无限期受阻,而是确保操作在无法满足读关注时返回错误。

更多信息,请参阅 "linearizable" 参考页。

具有读关注 "snapshot" 的查询会返回最近某个特定时间点跨分片出现的多数提交数据。仅当事务以写关注 "majority" 提交时,读关注 "snapshot" 才提供保证。

If a transaction is not part of a causally consistent session, upon transaction commit with write concern "majority", the transaction operations are guaranteed to have read from a snapshot of majority-committed data.
If a transaction is part of a causally consistent session, upon transaction commit with write concern "majority", the transaction operations are guaranteed to have read from a snapshot of majority-committed data that provides causal consistency with the operation immediately preceding the transaction start.

可用性:

读关注 "snapshot" 可用于

  • 多文档事务中的所有读取操作,读关注都在事务级别设置。

  • 以下方法可独立于多文档事务使用:

    所有其他读操作都禁止 "snapshot"

无论读关注级别如何,节点上的最新数据可能无法反映系统中数据的最新版本。

有关每个读关注级别的更多信息,请参阅:

对于不在多文档事务中的操作,您可以将 readConcern 级别指定为支持读关注的命令和方法的选项:

readConcern: { level: <level> }

要为 mongosh 方法 db.collection.find() 指定读关注级别,请使用 cursor.readConcern() 方法:

db.collection.find().readConcern(<level>)

对于多文档事务,您可以在事务级别设置读关注,而不是在单个操作级别。事务中的操作将使用事务级读关注。在集合和数据库级别设置的任何读关注在事务中都会被忽略。如果显式指定了事务级读关注,则在事务内也会忽略客户端级读关注。

重要

请勿为单个操作显然式设置读关注。要为事务设置读关注,请参阅读关注/写关注/读取偏好。

您可以在事务开始时设置读关注:

如果在事务开始时未指定,则事务将使用会话级读关注,如果未设置,则使用客户端级读关注。

更多信息,请参阅事务读关注。

对于因果一致会话中的操作,可使用 "local""majority""snapshot" 级别。但是,为了保证因果一致性,您必须使用 "majority"。有关详细信息,请参阅因果一致性。

以下操作支持读关注:

重要

要为事务中的操作设置读关注,请在事务级别而非单个操作级别设置读关注。请勿为事务中的各个操作显式设置读关注。更多信息,请参阅事务和读关注。

[1] 您不能将 $out$merge 阶段与读关注 "linearizable" 一起使用。换言之,如果将 "linearizable" 读关注为 db.collection.aggregate() 指定,则不能在管道中包含任一阶段。
[2] 读关注 "snapshot" 仅用于某些读操作和多文档事务。在事务中,您不能在分片集合上使用 distinct 命令或其帮助程序。

如果以下写入操作是多文档事务的一部分,则也可以接受读关注:

重要

要为事务中的操作设置读关注,请在事务级别而非单个操作级别设置读关注。

[3](1, 2) 读关注 "snapshot" 仅用于某些读取操作和多文档事务。对于事务,您可以在事务级别设置读关注。支持 "snapshot" 的事务操作对应于事务中可用的 CRUD 操作。更多信息,请参阅事务和读关注

本地数据库不支持读关注。 MongoDB 默默地忽略对本地数据库中集合操作的任何配置的读关注。

如果写入请求确认,您可以使用因果一致的会话来读取您自己的写入。

"majority" 写关注结合,"linearizable" 读关注使多个线程能够对单个文档执行读写,就像单个线程实时执行这些操作一样;换言之,这些读写的相应计划表被认为是可线性化的。

"majority" 不同,"linearizable" 读关注向从节点成员确认读取操作正在从能够使用 { w: "majority" } 写关注确认写操作的主节点成员进行读取。[4] 因此,具有可线性化读关注的读取可能比具有 "majority""local" 读关注的读取要慢得多。

始终将maxTimeMS与线性化读关注一起使用,以防大多数数据承载成员不可用。maxTimeMS确保操作不会无限期受阻,而是确保操作在无法满足读关注时返回错误。

例如:

db.restaurants.find( { _id: 5 } ).readConcern("linearizable").maxTimeMS(10000)
db.runCommand( {
find: "restaurants",
filter: { _id: 5 },
readConcern: { level: "linearizable" },
maxTimeMS: 10000
} )
[4]某些情况下,副本集中的两个节点可能会暂时认为它们是主节点,但最多只能有其中一个节点能够完成具有{ w: "majority" }写入关注的写入操作。可以完成{ w: "majority" }写入操作的节点是当前主节点,另一个节点是尚未识别其降级(通常是由于网络分区)的前主节点。发生这种情况时,尽管已请求读取偏好primary,但连接到前主节点的客户端可能会观察到过时数据,并且对前主节点的新写入操作最终将回滚。

MongoDB 包括对因果一致会话的支持。对于与因果一致会话关联的读操作,MongoDB 支持 afterClusterTime 读关注选项,该选项由与因果一致会话关联的操作的驱动程序自动设置。

重要

请勿为读取操作手动设置 afterClusterTime。MongoDB 驱动程序会自动为与因果一致会话关联的操作设置此值。不过,您可以提前会话的 ops/sec 和集群时间,以与其他客户端会话的操作保持一致。请参阅示例

注意

无法将 atClusterTimeafterClusterTime 一起指定。要将 atClusterTime 与读关注 "snapshot" 一起使用,必须禁用因果一致会话

要满足 afterClusterTime 值为 T 的读取请求,mongod 必须在其 oplog 到达时间 T 之后执行该请求。如果其 oplog 尚未到达时间 T,则 mongod 必须等待为该请求提供服务。

具有指定 afterClusterTime 的读取操作会返回同时满足读关注级别要求和所指定的 afterClusterTime 要求的数据。

对于与因果一致性会话无关联的读操作,未设置 afterClusterTime

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

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

来源
说明
clientSupplied
应用程序中指定了读关注问题。
customDefault
读关注源于一个自定义的默认值。参见 setDefaultRWConcern
implicitDefault
由于没有其他写关注规范,写关注源自服务器。

后退

GeoJSON 对象