读关注 (read concern)
借助 readConcern
选项,您可以控制从副本集和分片集群读取的数据的一致性和隔离属性。
通过有效使用写关注和读关注,您可以适当调整一致性和可用性保证的级别,例如等待更强的一致性保证,或者放松一致性要求以提供更高的可用性。
副本集和分片集群支持设置全局默认的读关注。未指定显式读关注的操作会继承全局默认的读关注设置。有关详细信息,请参阅 setDefaultRWConcern
。
读关注级别
以下是可用的读关注级别:
level | 说明 |
---|---|
查询从实例返回数据,不保证数据已写入副本集的多数成员(即,可能会回滚)。 可用性:因果一致的会话和事务不可使用读关注 对于分片集群, 更多信息,请参阅 | |
该查询返回已被副本集多数成员确认的数据。即使失败,读取操作返回的文档也是持久性的。 为了保证读关注“多数”,副本集成员在多数提交点从其内存数据视图返回数据。因此,读关注 可用性: 无论有没有因果一致的会话和事务,均可使用读关注 要求:要使用读关注级别 对于多文档事务中的操作,仅当事务以写关注“多数”提交时,读关注 更多信息,请参阅 | |
该查询返回的数据反映了在读取操作开始之前完成的所有成功的多数已确认的写入操作。该查询可能会等待并发执行的写入操作的数据复制到多数副本集成员之后,再返回结果。 如果多数副本集成员在读操作后崩溃并重新启动,且 将
您不能将 要求: 仅当读操作指定唯一标识单个文档的查询过滤时,才应用线性化读关注(read concern)ACID 一致性保证。此外,如果不满足以下条件,则线性化读关注(read concern)可能无法从一致的快照中读取,从而导致未返回与过滤匹配的文档:
如果满足前面的任何条件,查询将从一致的快照中读取以返回单个匹配的文档。 始终将 更多信息,请参阅 | |
具有读关注 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.可用性: 读关注
|
无论读关注级别如何,节点上的最新数据可能无法反映系统中数据的最新版本。
有关每个读关注级别的更多信息,请参阅:
readConcern
支持
读关注选项
对于不在多文档事务中的操作,您可以将 readConcern
级别指定为支持读关注的命令和方法的选项:
readConcern: { level: <level> }
要为 mongosh
方法 db.collection.find()
指定读关注级别,请使用 cursor.readConcern()
方法:
db.collection.find().readConcern(<level>)
事务和可用的读关注
对于多文档事务,您可以在事务级别设置读关注,而不是在单个操作级别。事务中的操作将使用事务级读关注。在集合和数据库级别设置的任何读关注在事务中都会被忽略。如果显式指定了事务级读关注,则在事务内也会忽略客户端级读关注。
重要
请勿为单个操作显然式设置读关注。要为事务设置读关注,请参阅读关注/写关注/读取偏好。
您可以在事务开始时设置读关注:
对于多文档事务,可以使用以下读关注级别:
归属多文档事务的写命令可以支持事务级读关注。
您可以在事务中创建集合和索引。如果显式创建集合或索引,则事务必须使用读关注
"local"
。如果隐式创建集合,则可以使用任何可用于事务的读关注。
如果在事务开始时未指定,则事务将使用会话级读关注,如果未设置,则使用客户端级读关注。
更多信息,请参阅事务读关注。
因果一致的会话和可用的读关注
对于因果一致会话中的操作,可使用 "local"
、"majority"
和 "snapshot"
级别。但是,为了保证因果一致性,您必须使用 "majority"
。有关详细信息,请参阅因果一致性。
支持读关注的操作
以下操作支持读关注:
重要
要为事务中的操作设置读关注,请在事务级别而非单个操作级别设置读关注。请勿为事务中的各个操作显式设置读关注。更多信息,请参阅事务和读关注。
[1] | 您不能将 $out 或 $merge 阶段与读关注 "linearizable" 一起使用。换言之,如果将 "linearizable" 读关注为 db.collection.aggregate() 指定,则不能在管道中包含任一阶段。 |
[2] | 读关注 "snapshot" 仅用于某些读操作和多文档事务。在事务中,您不能在分片集合上使用 distinct 命令或其帮助程序。 |
如果以下写入操作是多文档事务的一部分,则也可以接受读关注:
重要
要为事务中的操作设置读关注,请在事务级别而非单个操作级别设置读关注。
命令 | |||||
---|---|---|---|---|---|
✓ | ✓ | ||||
✓ | ✓ | ||||
✓ | ✓ | ||||
✓ | ✓ | ||||
✓ | |||||
✓ |
[3] | (1, 2) 读关注 "snapshot" 仅用于某些读取操作和多文档事务。对于事务,您可以在事务级别设置读关注。支持 "snapshot" 的事务操作对应于事务中可用的 CRUD 操作。更多信息,请参阅事务和读关注。 |
数据库不支持读关注local
本地数据库不支持读关注。 MongoDB 默默地忽略对本地数据库中集合操作的任何配置的读关注。
Considerations
读取自己的写入
如果写入请求确认,您可以使用因果一致的会话来读取您自己的写入。
实时顺序
与 "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 ,但连接到前主节点的客户端可能会观察到过时数据,并且对前主节点的新写入操作最终将回滚。 |
读操作和 afterClusterTime
MongoDB 包括对因果一致会话的支持。对于与因果一致会话关联的读操作,MongoDB 支持 afterClusterTime
读关注选项,该选项由与因果一致会话关联的操作的驱动程序自动设置。
重要
请勿为读取操作手动设置 afterClusterTime
。MongoDB 驱动程序会自动为与因果一致会话关联的操作设置此值。不过,您可以提前会话的 ops/sec 和集群时间,以与其他客户端会话的操作保持一致。请参阅示例。
注意
无法将 atClusterTime 与 afterClusterTime
一起指定。要将 atClusterTime 与读关注 "snapshot"
一起使用,必须禁用因果一致会话。
要满足 afterClusterTime
值为 T
的读取请求,mongod
必须在其 oplog 到达时间 T
之后执行该请求。如果其 oplog 尚未到达时间 T
,则 mongod
必须等待为该请求提供服务。
具有指定 afterClusterTime
的读取操作会返回同时满足读关注级别要求和所指定的 afterClusterTime
要求的数据。
对于与因果一致性会话无关联的读操作,未设置 afterClusterTime
。
读关注来源
MongoDB 会跟踪读关注 provenance
,而后者表示特定读关注的来源。您可能会看到 getLastError
指标、读关注错误对象和 MongoDB 日志中显示 provenance
。
下表显示了可能的读关注 provenance
值及其重要性:
来源 | 说明 |
---|---|
clientSupplied | 应用程序中指定了读关注问题。 |
customDefault | 读关注源于一个自定义的默认值。参见 setDefaultRWConcern 。 |
implicitDefault | 由于没有其他写关注规范,写关注源自服务器。 |