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

读取关注点

本页内容

  • 读取关注级别
  • readConcern 支持
  • 考虑事项

readConcern 选项允许您控制从副本集分片集群读取的数据的一致性和隔离属性。

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

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

以下读取关注级别可用

级别
描述

查询返回的数据可能未被写入到副本集大多数成员(即可能被回滚)。

针对主节点和辅助节点的读取默认值。

可用性:读关注 "local" 可用于因果一致会话和事务。

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

查询返回的数据可能未被写入到副本集大多数成员(即可能被回滚)。

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

对于分片集群,"available" 读取关注提供了各种读取关注中最低延迟的读取。然而,这以一致性为代价,因为当从分片集合读取时,"available" 读取关注可能会返回"available" 读取关注可以返回"available" 读取关注可以返回孤儿文档。为了避免从分片集合读取时返回孤儿文档的风险,请使用不同的读取关注,例如读取关注 "local"

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

查询返回已由大多数副本集成员确认的数据。由读取操作返回的文档是持久的,即使在发生故障的情况下。

为了满足“多数”读取关注,副本集成员从其数据的大多数提交点的内存视图返回数据。因此,读取关注 "majority" 的性能成本与其他读取关注相当。

可用性

读取关注 "majority" 可与或无需因果一致会话和事务一起使用。

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

对于多文档事务中的操作,只有在事务以 "majority" 写关注提交时,读取关注 "majority" 才提供其保证。否则,"majority" 读取关注不提供对事务中读取的数据的任何保证。

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

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

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

当将 writeConcernMajorityJournalDefault 设置为 false 时,MongoDB 不会等待将 w: "majority" 写入磁盘日志后再确认写入。因此,在给定副本集中多数节点发生暂时性丢失(例如,崩溃和重启)的情况下,可能会回滚 "majority" 写入操作。

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

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

您不能将 $out$merge 阶段与读取关注点 "linearizable" 结合使用。也就是说,如果您为 db.collection.aggregate() 指定 "linearizable" 读取关注点,则不能在管道中包含这两个阶段。

需求

可线性化读取关注点仅适用于读取操作指定一个唯一标识单个文档的查询过滤器。此外,如果以下任何标准都不满足,可线性化读取关注点可能不会从一致的快照中读取,导致与过滤器匹配的文档不被返回

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

  • 没有并发更新会修改查询的搜索键。

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

如果满足上述任何标准,则查询将从一致的快照中读取以返回单个匹配的文档。

在多数数据承载成员不可用的情况下,始终使用 maxTimeMS 与可线性化读取关注点。 maxTimeMS 确保操作不会无限期地阻塞,并且如果读取关注点无法满足,则操作返回错误。

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

具有读取关注点 "snapshot" 的查询返回最近过去特定单一点时间戳在分片上显示的多数已提交数据。只有当事务与写入关注点 "majority" 提交时,读取关注点 "snapshot" 才提供其保证。

如果事务不是因果一致性会话的一部分,则事务提交时与写入关注点 "majority",则保证事务操作已从多数已提交数据的快照中读取。
如果一个事务是因果一致性会话的一部分,在事务提交时使用写关注"majority"(多数写关注),则事务操作将保证从多数已提交数据的快照中读取,该快照与事务开始前立即执行的操作提供因果一致性。

可用性

以下场景可以使用读关注"snapshot"(快照读关注):

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

  • 以下非多文档事务的方法:

    所有其他读操作均禁止使用"snapshot"

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

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

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

readConcern: { level: <level> }

要指定以下操作的读关注级别:mongosh 方法 db.collection.find(),使用 cursor.readConcern() 方法

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

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

重要

不要显式设置单个操作的读关注点。要设置事务的读关注点,请参阅 读关注点/写关注点/读优先级。

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

  • 对于多文档事务,以下读关注点级别可用

  • 作为 多文档事务一部分的写命令可以支持事务级别的读关注点。

  • 您可以在事务内部 创建集合和索引。如果显式创建集合或索引,事务必须使用读关注点 "local"。如果您隐式创建集合,可以使用事务可用的任何读关注点。

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

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

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

以下操作支持读取关注度

重要

要为事务中的操作设置读取关注度,您需要在事务级别设置读取关注度,而不是在单个操作级别。不要显式地为事务中的单个操作设置读取关注度。有关更多信息,请参阅事务和读取关注度。

[1] 您不能将 $out$merge 阶段与读取关注点 "linearizable" 结合使用。也就是说,如果您为 db.collection.aggregate() 指定 "linearizable" 读取关注点,则不能在管道中包含这两个阶段。
[2] 读取关注 "快照" 只适用于某些读取操作和多文档事务。在一个事务中,你无法在分片集合上使用 distinct 命令或其辅助命令。

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

重要

为了设置事务中操作的读取关注,你在事务级别设置读取关注,而不是在单个操作级别。

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

local 数据库 上不支持读取关注。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驱动程序会自动为与因果一致性会话相关的操作设置此值。但是,您可以提前操作时间和会话的集群时间,例如与其他客户端会话的操作保持一致。例如,请参阅示例。

注意

不能同时指定atClusterTimeafterClusterTime。要使用具有读取关注点"snapshot"atClusterTime,必须禁用因果一致性会话。

为了满足具有afterClusterTime值为T的读取请求,mongod必须在其oplog达到时间T之后执行请求。如果其oplog尚未达到时间T,则mongod必须等待处理请求。

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

对于与因果一致性会话不相关的读取操作,afterClusterTime未设置。

MongoDB跟踪读取关注点provenance,该provenance指示特定读取关注点的来源。您可以在getLastError度量标准、读取关注点错误对象和MongoDB日志中看到provenance。

以下表格显示了可能的读取关注点provenance值及其含义

来源
描述
clientSupplied
读取关注点是在应用程序中指定的。
customDefault
读取关注级别来自自定义定义的默认值。请参阅setDefaultRWConcern
implicitDefault
在没有其他读取关注级别指定的情况下,读取关注级别来自服务器。

返回

GeoJSON 对象