使用 readConcern 选项可控制从 副本集和分片的集群读取的数据的一致性和隔离性。
通过有效使用写入关注和读关注,您可以调整一致性和可用性ACID 一致性保证的级别。示例,您可以等待更强的一致性ACID 一致性保证,或者放松一致性要求以获得更高的可用性。
副本集和集群支持全局默认的读关注(read concern)。没有显式读关注(read concern)的操作会继承全局默认。有关更多信息,请参阅 setDefaultRWConcern。
读关注级别
以下是可用的读关注级别:
level | 说明 |
|---|---|
查询从实例返回数据,但不保证数据已写入大多数副本集成员。数据可能会回滚。 可用性:因果一致的会话和事务不可使用读关注 对于分片集群, 更多信息,请参阅 | |
查询返回得到大多数副本集节点确认的数据。即使发生故障,返回的文档也是持久性的。 为了完成读关注(read concern) 可用性:无论有没有因果一致的会话和事务,读关注(read concern) 要求:副本集必须使用WiredTiger存储引擎。 对于多文档事务,仅当ACID 事务以写关注(write concern)“大多数”提交时,读关注(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.可用性:读关注(read concern)
|
无论读关注级别如何,节点上的最新数据可能无法反映系统中数据的最新版本。
有关每个读关注级别的更多信息,请参阅:
readConcern 支持
读关注选项
对于不在多文档事务中的操作,您可以将 readConcern 级别指定为支持读关注的命令和方法的选项:
readConcern: { level: <level> }
要为 mongosh 方法 db.collection.find() 指定读关注级别,请使用 cursor.readConcern() 方法:
db.collection.find().readConcern(<level>)
事务和可用的读关注
对于多文档事务,请在ACID 事务级别而不是单个操作级别设立读关注(read concern)。事务操作使用事务级读关注(read concern)。在集合和数据库级别设立的读关注(read concern)在事务中将被忽略。如果您显式设立事务级别的读关注(read concern),则也会忽略客户端级别的读关注(read concern)。
重要
请勿为单个操作显式设立读关注(read concern)。要为事务设立读关注(read concern),请参阅读关注、写关注和读取偏好。
您可以在事务开始时设置读关注:
多文档事务支持以下读关注(read concern)级别:
归属多文档事务的写命令可以支持事务级读关注。
您可以在事务中创建集合和索引。如果显式创建集合或索引,则事务必须使用读关注
"local"。如果隐式创建集合,则可以使用任何可用于事务的读关注。
如果在事务开始时未指定,则事务将使用会话级读关注,如果未设置,则使用客户端级读关注。
更多信息,请参阅事务读关注。
因果一致的会话和可用的读关注
对于因果一致会话中的操作,可以使用"local"、"majority"和"snapshot"级别。为保证因果一致性,请使用 "majority"。有关详细信息,请参阅因果一致性。
支持读关注的操作
以下操作支持读关注:
重要
要为事务中的操作设置读关注,请在事务级别而非单个操作级别设置读关注。请勿为事务中的各个操作显式设置读关注。更多信息,请参阅事务和读关注。
| [1] | 您不能将 $out 或 $merge 阶段与读关注 "linearizable" 一起使用。换言之,如果将 "linearizable" 读关注为 db.collection.aggregate() 指定,则不能在管道中包含任一阶段。 |
| [2] | 读关注 "snapshot" 仅用于某些读操作和多文档事务。在事务中,您不能在分片集合上使用 distinct 命令或其帮助程序。 |
如果以下写入操作是多文档事务的一部分,则也可以接受读关注:
重要
要为事务中的操作设置读关注,请在事务级别而非单个操作级别设置读关注。
命令 | |||||
|---|---|---|---|---|---|
✓ | ✓ | ||||
✓ | ✓ | ||||
✓ | ✓ | ||||
✓ | ✓ | ||||
✓ | |||||
✓ |
| [3] | (1, 2) 读关注(read concern) "snapshot" 仅适用于某些读操作和多文档事务。对于事务,请在ACID 事务级别设立读关注(read concern)。支持"snapshot"的事务操作对应于事务中可用的增删改查操作。有关更多信息,请参阅事务和读关注(read concern)。 |
local 数据库不支持读关注
本地数据库不支持读关注。MongoDB默默地忽略对本地数据库中集合操作的任何配置的读关注(read concern)。
Considerations
读取自己的写入
如果写入请求确认,您可以使用因果一致的会话来读取您自己的写入。
实时顺序
与 "majority" 写关注(write concern)结合,"linearizable" 读关注(read concern)使多个线程能够对单个文档执行读取和写入,就像单个线程实时执行这些操作一样。这些读取和写入的相应安排被认为是可线性化的。
性能比较
与 "majority" 不同,"linearizable" 读关注(read concern)与从节点(secondary node from replica set)成员确认该读操作从主节点读取,该主节点 (primary node in the replica set)能够使用 { w: "majority" } 写关注(write concern)确认写入。[4] 具有线性化读关注(read concern)的读取可能比具有 "majority" 或 "local" 读关注的读取慢得多。
如果大多数数据承载节点不可用,请始终将 maxTimeMS 与线性化读关注(read concern)一起使用。maxTimeMS 确保操作在无法满足读关注(read concern)时返回错误,而不是无限期阻塞。
例如:
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支持因果一致的会话。对于因果一致会话中的读操作,驱动程序会自动设立afterClusterTime读关注(read concern)选项。
重要
请勿为读取操作手动设立afterClusterTime。MongoDB驱动程序会自动为因果一致会话中的操作设立此值。但是,您可以提前会话的操作时间和集群时间,以便与另一个客户端会话的操作一致。有关示例,请参阅示例。
注意
您不能将 atClusterTime 与 afterClusterTime 一起指定。要将 atClusterTime 与读关注(read concern)"snapshot" 一起使用,请禁用因果一致会话。
要满足 afterClusterTime 值为 T 的读取请求,mongod 必须在其oplog到达时间 T 之后执行该请求。如果其oplog尚未到达时间 T,则 mongod 将等待为该请求提供服务。
具有指定 afterClusterTime 的读取操作会返回同时满足读关注(read concern)级别要求和指定 afterClusterTime 要求的数据。
对于与因果一致性会话无关联的读操作,未设置 afterClusterTime。
读关注来源
MongoDB追踪读关注(read concern)provenance,它表示读关注(read concern)的来源。provenance 值显示在 getLastError 指标、读关注(read concern)错误对象和MongoDB日志中。
下表显示了可能的读关注 provenance 值及其重要性:
来源 | 说明 |
|---|---|
| 应用程序中指定了读关注问题。 |
| 读关注源于一个自定义的默认值。参见 |
| 由于没有其他写关注规范,写关注源自服务器。 |