读关注 (read concern) "linearizable"
版本 3.4 中的新增功能。
该查询返回的数据反映了在读取操作开始之前完成的所有成功的多数已确认的写入操作。该查询可能会等待并发执行的写入操作的数据复制到多数副本集成员之后,再返回结果。
如果大多数副本集成员在读操作后崩溃并重新启动,并且 writeConcernMajorityJournalDefault
设立为默认状态true
,则读操作返回的文档是持久性化的。
将 writeConcernMajorityJournalDefault
设置为 false
时,MongoDB 不会等待 w: "majority"
写入在写入到磁盘日志后才确认写入。例如,"majority"
写操作可能会在给定副本集中的大部分节点发生临时断连(例如崩溃和重启)的情况下回滚。
您只能为primary
上的读取操作指定线性化读关注。
提示
始终将maxTimeMS
与线性化读关注一起使用,以防大多数数据承载成员不可用。maxTimeMS
确保操作不会无限期受阻,而是确保操作在无法满足读关注时返回错误。
要求
仅在读操作指定唯一标识单个文档的查询筛选条件时,才适用线性化读关注保证。此外,如果不满足以下条件,则线性化读关注可能无法从一致的快照中读取,从而导致未返回与过滤器匹配的文档:
如果满足前述任何条件,查询将从一致快照中读取,返回单个匹配文档。
因果一致的会话
读关注 "linearizable"
不可用于因果一致的会话。
聚合限制
您不能将 $out
或 $merge
阶段与读关注 "linearizable"
结合使用。也就是说,如果您为 db.collection.aggregate()
指定"linearizable"
读关注,则不能在管道中包含任一阶段。
实时顺序
与 "majority"
写关注结合使用时,"linearizable"
读关注允许多个线程对单个文档执行读取和写入,就像单个线程实时执行这些操作一样;也就是说,这些读取和写入的相应计划被视为可线性化。
读取自己的写入
如果写入请求确认,您可以使用因果一致的会话来读取您自己的写入。
性能比较
与 "majority"
不同,"linearizable"
读关注向从节点确认,读取操作正在从能够确认具有 { w: "majority" }
写关注的写入的主节点中读取。[1] 因此,具有可线性化读关注的读取可能比具有 "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 } )
[1] | 在某些情况下,副本集中的两个节点可能会暂时认为它们是主节点,但最多只能有其中一个节点能够完成具有{ w:
"majority" } 写入关注的写入操作。可以完成{ w: "majority" } 写入操作的节点是当前主节点,另一个节点是尚未识别其降级(通常是由于网络分区)的前主节点。发生这种情况时,尽管已请求读取偏好primary ,但连接到前主节点的客户端可能会观察到过时数据,并且对前主节点的新写入操作最终将回滚。 |