Read Concern读关注
在本页面
读关注 选项允许你控制从复制集和分片集群读取数据的一致性和隔离性。
将MongoDB驱动程序更新到MongoDB 3.2或更高版本以支持读关注。
以下为可用的读关注级别:
level | Description |
查询并从实例返回数据,但不能保证该数据已被写入大多数副本集成员(即可能已经回滚)。 **默认为:**如果读取与因果关系一致的会话没有关联,则针对副节点读 **可用性:**读关注 available 无法用于有因果关系一致的会话和事务中。 对于分片群集,"available" 读关注提供了各种读关注中尽可能最低的延迟。但是,这是以牺牲一致性为代价的,因为从分片的集合中进行读取时,"available" 读关注会返回孤立的文档。为了避免从分片的集合中读取时返回孤立文档的风险,可使用其他读关注,如"local" 读关注。 更多的信息,请参考"available" 页 3.6版本的新功能 | |
为了满足读关注“majority”,副本集成员从其内存视图中返回多数提交点提交的数据。这样,读关注 "majority" 在性能成本上可与其他读关注相媲美。 可用性: 读关注"majority" 可用于有或没有因果关系一致的会话和事务中。 对于具有三名成员的主从仲裁(PSA)架构的部署,可以禁用读关注"majority" ;但是,这对change streams(仅在MongoDB 4.0和更早版本中)和分片群集上的事务有影响。有关更多信息,请参见禁用读关注Marjority.。 **要求:**若要使用"majority" 的读关注级别,副本集必须使用WiredTiger存储引擎。 注意: 对于多文档事务中的操作,仅当事务以写关注"majority" 提交时,读关注"majority" 才提供其保证。否则,"majority" 读关注不能保证其在事务中读取的数据。 更多的信息,请参考"majority" 页 | |
该查询返回的数据表示了这些数据在操作开始之前已成功在大多数节点确认写入。查询可能会等待并发执行的写操作传播到大多数副本集成员,然后返回结果。 如果大多数副本集成员崩溃并在读操作后重新启动,则如果将 writeConcernMajorityJournalDefault 设 置为默认状态true,则读操作返回的文档将还是有效的。 将writeConcernMajorityJournalDefault 设置为false 时,MongoDB不会等待w: "majority" 在确认 写入之前先要写入磁盘日志。这样,如果给定副本集中大多数节点的瞬时丢失(例如崩溃和重新启动),majority 写操作可能会回滚。 可用性: 读关注"linearizable" 不适用于因果一致的会话和事务。 你可以仅对主节点上的读操作指定为线性读关注。 你不能将$out 或$merge 操作与读关注"linearizable" 结合使用。也 就是说,如果为db.collection.aggregate() 指定为"linearizable" 读关注,则不能在管道中使用任何的操作。 **要求:**linearizable读关注仅保证在读操作指定了唯一标识单个文档的查询过滤器时可用。 请始终将maxTimeMS 与linearizable读关注一起使用,以防止大多数数据承载成员不可用。maxTimeMS 确保操作不会无限期地阻塞,而是确保如果无法满足读取要求,则操作将返回错误。 更多的信息,请参考"linearizable" 页 | |
如果事务不是因果一致会话的一部分,写关注为 "majority" 且在事务提交后,可以确保事务操作已从多数提交数据的快照中读取。 如果事务是因果一致会话的一部分,写关注为"majority" 且在事务提交后,可以确保事务操作已从多数提交数据的快照中读取,该快照提供了与紧接事务开始之前的操作的因果一致性。 读关注"snapshot" 仅可用于多文档事务。 对于分片群集上的事务,如果事务中的任何操作涉及已被禁用读关注“majority”的分片,那你就不能对该事务使用读关注"snapshot" 。你只能对事务使用读关注"local" 或"majority" 。 |
有关每个阅读关注级别的更多信息,请参见:
readConcern: { level: <level> }
db.collection.find().readConcern(<level>)
对于多文档事务,应在事务级别而不是在单个操作级别设置读关注。事务中的操作将使用事务级别的读关注。事务内部将忽略在集合和数据库级别设置的任何读关注。如果显式指定了事务级别的读关注点,则在事务内部也将忽略客户端级别的读关注点。
你可以在事务开始时设置读关注:
如果未在事务开始时指定,则事务将使用会话级的读关注,或者如果未设置,则使用客户端级的读关注。
下列的操作支持读关注:
命令/方法 | |||||
✓ | ✓ | ✓ | | ✓ | |
✓ | ✓ | ✓ | ✓ | ✓ | |
✓ | ✓ | ✓ | ✓ | ✓ | |
✓ | ✓ | ✓ | ✓ | ✓ | |
✓ | ✓ | ✓ | ✓ | ✓ | |
✓ | | | | ✓ | |
✓ | ✓ | ✓ | ✓ | ✓ | |
✓ | | ✓ | ✓ | |
你不能将 $out 或者 $merge 阶段与读关注的"linearizable" 结合使用。也就是说,如果为db.collection.aggregate() 指定"linearizable" 读关注,则不能在管道中包括任何一个阶段。 | |
下列的写操作页能接受读关注,但必须是多文档事务的一部分:
在为事务中的操作设置读关注时,请在事务级别而不是在单个操作级别设置读关注
Command 命令 | |||||
✓ | | | ✓ | | |
✓ | | | ✓ | | |
✓ | | | ✓ | | |
✓ | | | ✓ | |
[3] | (1, 2_)_读关注“SNAPSHOT”仅适用于多文档事务,并且对于事务,您可以在事务级别设置读关注。支持“SNAPSHOT”的操作对应于事务中可用的CRUD操作。有关更多信息,请参见事务和读关注 |
| |
在版本3.6中更改
在MongoDB 3.6之前,您必须使用
{ w: "majority" }
写关注发出写操作,然后对读操作使用 "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
} )
在某些情况下,副本集中的两个节点可能会短暂地认为它们是主节点,但至多,其中一个节点将能够以 { w: "majority" } 写关注完成。 可以完成{ w: "majority" } 写入的节点是当前主节点,另一个节点是前主节点,由于网络分区的原因,该主节点尚未意识到其降级。 发生这种情况时,尽管请求的读优先级为主节点,但连接到前主界定啊的客户端仍可能会读到过时的数据,并且最终将对前主节点新写入的进行回滚。 | |
| |
3.6 版本新加入
MongoDB 3.6引入了对因果一致会话的支持。 对于与因果一致的会话相关联的读操作,MongoDB 3.6引入了
afterClusterTime
读关注选项,驱动程序会自动将afterClusterTime
读关注选项设置为与因果一致的会话相关联的操作。[warning] 重要不要手动为读操作设置afterClusterTime
。 MongoDB驱动程序会针对与因果一致的会话相关联的操作自动设置此值。 但是,您可以提前会话的操作时间和群集时间,以便与另一个客户端会话的操作保持一致。 有关示例,请参见示例。
使用指定的
afterClusterTime
的读操作将返回满足读关注级别要求和指定的 afterClusterTime
要求的数据。对于与因果一致会话无关的读操作,未设置
afterClusterTime
。下表显示了可能的阅读问题provenance值及其重要性:
出处 | 描述 |
---|---|
clientSupplied | read关注点是在应用程序中指定的。 |
customDefault | |
implicitDefault | 在没有其他所有读取关注规范的情况下,读取关注源自服务器。 |
译者:杨帅 张琦
校对:杨帅
最近更新 1yr ago