写入关注与读关注与备份恢复与运维

共 19 题
📑 题目列表 19 题
#
★★★

1. mongodump/mongorestore 逻辑备份与文件系统快照物理备份在一致性、速度、跨版本兼容与恢复粒度上有何差异?

请对比 mongodump/mongorestore 逻辑备份与文件系统快照物理备份在一致性、速度、跨版本兼容与恢复粒度上的差异?

  • 逻辑备份:BSON 数据导出,跨版本兼容好,速度慢
  • 物理备份:文件系统快照,速度快,跨版本兼容差
  • 一致性:逻辑备份需 oplog 保证,物理快照需一致

mongodump/mongorestore 是逻辑备份,导出 BSON 数据与索引,恢复粒度细(可恢复单个集合/库),跨版本兼容好(可迁移到不同版本/架构),但速度慢(逐文档导出),且备份时需配合 oplog 才保证一致性(否则可能不一致)。文件系统快照是物理备份,直接复制数据文件,速度快、可并发复制,但跨版本兼容差(需同版本/同引擎),恢复粒度粗(通常整库整机恢复),安全性依赖快照一致性(需副本集一致性快照或 fsyncLock)。选择:追求速度与大规模用物理快照,追求跨版本迁移与细粒度用逻辑备份,两者也可结合(快照 + oplog 归档)。

逻辑 vs 物理备份的差异是"速度/粒度 vs 兼容性"。逻辑备份逐文档、跨版本好、粒度细;物理快照快、跨版本差、粒度粗。理解"一致性保证方式"与"跨版本兼容"是关键。选型取决于迁移需求与恢复粒度。

#
★★★

2. MongoDB 副本集备份如何保证一致性快照(对 secondary 做文件系统快照、或快照配合 oplog、db.fsyncLock 锁写的代价)?

请说明 MongoDB 副本集备份如何保证一致性快照,包括对 secondary 做文件系统快照、快照配合 oplog、db.fsyncLock 锁写的代价?

  • 对 secondary 做文件系统快照避免阻塞主库
  • 快照配合 oplog 补全时间点
  • db.fsyncLock 锁写保证一致但阻塞写入

副本集备份的一致性快照可选多种方式。对 secondary 做文件系统快照:在 secondary 上做快照,不阻塞主库写入,但需保证 secondary 快照点一致(快照瞬间数据文件一致),且快照可能滞后于主库,需配合 oplog 补全到目标时间点。快照配合 oplog:先做快照,再用 oplog 回放,把数据恢复到快照之后的任意时间点,实现一致。db.fsyncLock 锁写:把待备份节点锁写(fsyncLock),禁止写入后再做快照,保证快照完全一致,但代价是阻塞该节点写入(对主库会阻塞写入,对 secondary 影响复制),仅适合维护窗口。推荐:对 secondary 做快照 + oplog 归档,兼顾一致性与不阻塞主库。

一致性备份的核心是"快照点一致性 + 时间点恢复"。对 secondary 快照不阻塞主库,配合 oplog 补全时间点;fsyncLock 强制一致但阻塞写入。理解"快照 + oplog 组合"与"fsyncLock 代价",是设计备份的关键。推荐对 secondary 快照避免阻塞主库。

#
★★★

3. 分片集群备份为何要先停 balancer 再对各 shard 与 config server 取同一时间点快照?不停 balancer 会导致怎样的跨分片不一致?

请解释分片集群备份为何要先停 balancer 再对各 shard 与 config server 取同一时间点快照,以及不停 balancer 会导致怎样的跨分片不一致?

  • 停 balancer 避免迁移期间快照不一致
  • 各 shard 与 config server 需同一时间点快照
  • 不停 balancer 会导致 chunk 数据与元数据不一致

分片集群备份的一致性要求"各 shard 与 config server 的元数据与实际数据一致"。若在备份时 balancer 正在迁移 chunk,chunk 的数据可能从一个分片复制到另一个分片,而元数据(config server)尚未完成切换,导致快照中出现"数据在源分片但元数据指向目标分片"或反之的不一致,恢复后数据与元数据错位,无法正常使用。因此备份前应先停止 balancer(sh.stopBalancer()),等迁移完成,再对各 shard 与 config server 取同一时间点的快照,保证元数据与实际数据一致。不停 balancer 导致的跨分片不一致,轻则数据缺失/重复,重则集群无法路由。备份完成后可重新启动 balancer。

分片集群备份的核心是"元数据与数据的一致性"。停 balancer 避免迁移中快照与元数据错位,同一时间点快照保证跨分片一致。理解"迁移与元数据切换的时差造成不一致",是回答的关键。停 balancer 是分片备份的标准前置步骤。

#
★★★

4. 如何借助 oplog 做时间点恢复(mongorestore --oplogReplay --oplogLimit)?oplog 大小与可回溯窗口(滚动覆盖)如何规划?

请说明如何借助 oplog 做时间点恢复(mongorestore --oplogReplay --oplogLimit),以及 oplog 大小与可回溯窗口如何规划?

  • mongodump 时用 --oplog 导出 oplog
  • mongorestore --oplogReplay 回放 oplog 到目标时间点
  • --oplogLimit 限制回放时间点

时间点恢复借助 oplog:mongodump 备份时用 --oplog 把备份时刻的 oplog 一并导出,mongorestore 恢复时用 --oplogReplay 回放 oplog,把数据恢复到备份时刻之后的目标时间点;--oplogLimit 可指定回放到某个时间戳(如恢复到 10:00 的数据),实现精确时间点恢复。oplog 大小决定可回溯窗口:oplog 是环形缓冲,容量有限,只保留最近一段时间的操作;可回溯窗口 = oplog 容量 / 写入速率。若写入速率高而 oplog 小,窗口短,时间点恢复的范围受限。规划时应评估写入速率与需要的恢复窗口,设置足够大的 oplog 大小(--oplogSize 或 rs.resizeOplog),保证可回溯窗口覆盖所需的恢复时间范围。

oplog 时间点恢复的核心是"备份含 oplog + 回放到目标时间点"。理解 --oplogReplay/--oplogLimit 与"oplog 容量决定回溯窗口",是设计恢复能力的关键。窗口 = 容量/写入速率,规划 oplog 大小以匹配恢复需求。oplog 环形覆盖是恢复范围的上限。

#
★★★

5. MongoDB 副本集滚动升级的标准流程(先升级 secondary → rs.stepDown → 升级原 primary)是什么?如何验证选举与版本一致?

请说明 MongoDB 副本集滚动升级的标准流程,以及如何验证选举与版本一致?

  • 升级顺序:先 secondary,再 stepDown 原 primary,最后升级原 primary
  • stepDown 触发选举保证无主时间短
  • 验证版本一致与选举正常

副本集滚动升级的标准流程是:先逐个升级所有 secondary(保持 primary 不变,不影响写入),然后对 primary 执行 rs.stepDown() 主动让位,触发选举产生新的 primary(此时集群仍可用),再升级原 primary(此时它是 secondary)。这样保证任意时刻至少多数派节点在线,集群不中断,无主时间短(stepDown 主动触发)。升级时逐个节点升级、验证其生效后再下一个。验证:升级完成后用 rs.status() 检查所有节点版本一致(同一二进制版本)、选举正常(rs.stepDown 或 rs.reconfig 后能正确选主)、主从同步正常(rs.status() 的 lag 为 0)。滚动升级避免停机,是运维的标准做法。

滚动升级的核心是"先 secondary 后 primary + stepDown 主动让位"。理解"升级顺序保证多数派在线、stepDown 缩短无主时间",是回答的关键。验证版本一致与选举正常,确保升级后集群健康。滚动升级避免停机,是生产常用流程。

#
★★★

6. MongoDB 4.2+ 索引构建机制(先在 secondary 构建、最后 primary 构建以缩短影响)与旧版前台/后台构建有何差异?构建期间写入如何处理?

请说明 MongoDB 4.2+ 索引构建机制(先在 secondary 构建、最后 primary 构建)与旧版前台/后台构建的差异,以及构建期间写入如何处理?

  • 4.2+ 混合构建:先在 secondary 构建,最后 primary 构建
  • 旧版前台构建阻塞、后台构建不阻塞
  • 构建期间写入继续处理

MongoDB 4.2+ 的索引构建采用混合机制:先在所有 secondary 上构建索引(不阻塞 secondary 读取),最后在 primary 上构建并完成,缩短对 primary 的影响。旧版有两种方式:前台构建(foreground)会阻塞集合的读写,直到构建完成,读与写都暂停,仅适合小集合或维护窗口;后台构建(background)允许读写并发,但构建期间占用 IO 与资源。4.2+ 的新机制(混合构建)在 secondary 上构建时不阻塞其读取,primary 最后的构建阶段才短暂影响,整体影响更小。构建期间写入:前台构建阻塞写入,后台/混合构建允许写入继续(写入会进入索引构建,可能增加构建时间)。选择构建方式需权衡影响与构建时间。

索引构建的演进是"从阻塞到尽量不阻塞"。4.2+ 混合构建先在 secondary 构建、最后 primary 构建,缩短影响;前台构建阻塞、后台构建允许写入。理解"构建期间写入处理"与"新旧机制差异",是管理索引构建的关键。生产环境优先用 4.2+ 混合构建。

#
★★★

7. readConcern: majority 如何维护已提交快照并推进?与 local/available 读相比,实现代价与一致性收益是什么?

请说明 readConcern: majority 如何维护已提交快照并推进,以及与 local/available 读相比的实现代价与一致性收益?

  • majority 读关注只读多数派已提交的数据
  • 维护已提交快照并随时间推进
  • 与 local/available 相比的代价与一致性

readConcern: majority 保证读到的数据是已被多数派节点确认(已提交)的数据,不会读到后来被回滚的未提交数据。MongoDB 维护一个"已提交快照"(local snapshot),记录当前多数派已提交的最新时间点,majority 读基于该快照;随着多数派确认持续推进,快照向前推进。与 local/available 读相比:local 读返回本地节点当前可见的数据(可能是未提交/未复制到多数派的数据),速度快但可能读到不一致;available 类似本地且不等待多数派,主要用于分片集群提升可用性;majority 读需等待并基于多数派已提交快照,保证强一致但实现代价高(需维护已提交快照、等待多数派确认、延迟更高)。收益是避免读到已回滚数据,保证一致性。

majority 读关注的核心是"只读多数派已提交数据 + 维护已提交快照"。理解"local/available 快但可能不一致、majority 慢但强一致"的取舍,是回答的关键。majority 的实现代价是维护快照与等待确认,收益是强一致。选型取决于一致性与性能要求。

#
★★★

8. w:majority 在少数派分区时写入为何阻塞?j 与 w 的组合语义是什么,如何配置以满足不同 RPO 要求?

请解释 w:majority 在少数派分区时写入为何阻塞,j 与 w 的组合语义,以及如何配置以满足不同 RPO 要求?

  • w:majority 需多数派确认,少数派分区无法确认
  • j 表示是否写 journal(日志持久化)
  • RPO 即恢复点目标,配置满足不同 RPO

w:majority 要求写入被多数派节点确认后才返回成功。当发生网络分区,节点处于少数派(不能与多数派通信)时,写入无法被多数派确认,因此写入会阻塞(等待超时或失败),这是为了防止"少数派分区写入数据后丢失/脑裂"而牺牲可用性换取一致性。j 与 w 的组合:w 决定需多少节点确认(w:1 本节点、w:majority 多数派),j 决定是否要求写 journal(j:true 数据已落 journal 才确认,防崩溃丢数据)。配置满足 RPO:RPO 越小要求越强,w:majority + j:true 提供最近一次确认的持久性,可满足 RPO 接近 0 的需求;w:1 + j:false 则 RPO 大(可能丢较多数据)。运维按业务 RPO 要求选择 w 与 j 组合。

w:majority 阻塞少数派写入是"一致性优先于可用性"。理解"多数派确认 + 分区阻塞"与"j 控 journal 持久化",是回答的关键。RPO 由 w + j 组合决定:组合越强 RPO 越小,但延迟越高。按 RPO 需求配置写关注。

#
★★

9. 如何用 database profiler(慢查询采样)与 db.currentOp() 定位慢查询与长事务/长操作?

请说明如何用 database profiler(慢查询采样)与 db.currentOp() 定位慢查询与长事务/长操作?

  • profiler 记录慢查询日志
  • db.currentOp() 查看当前运行的操作
  • 定位慢查询与长事务

database profiler 用于记录慢查询:设置 profiling level(如慢查询阈值 ms),MongoDB 会把超过阈值的查询记录到 system.profile 集合,可查询慢查询的耗时、计划、扫描文档数等。db.currentOp() 用于查看当前正在运行的操作,显示操作类型、耗时、是否等待锁、事务状态等,可定位长事务、长操作、阻塞操作。定位流程:先用 profiler 找出慢查询(分析其索引与计划),再用 db.currentOp() 看当前是否有长事务/长操作占用资源或持有锁,必要时用 db.killOp() 终止问题操作。两者配合可全面定位性能问题。

profiler 定位历史慢查询,currentOp 定位当前运行操作。理解"profiler 记录慢查询 + currentOp 查看长操作/锁等待",是性能诊断的关键。结合 explain 分析计划,可深入优化。当前操作饥饿或锁等待用 currentOp 发现。

#
★★

10. mongorestore 的 --drop、--nsInclude/--nsExclude、--restoreDbUsersAndRoles 各自适用什么恢复场景?

请说明 mongorestore 的 --drop、--nsInclude/--nsExclude、--restoreDbUsersAndRoles 各自适用的恢复场景?

  • --drop:恢复前删除目标集合,避免重复
  • --nsInclude/--nsExclude:选择/排除要恢复的命名空间
  • --restoreDbUsersAndRoles:恢复用户与角色

mongorestore 的常用选项适用不同场景。--drop:在恢复前删除目标集合中已存在的文档,再插入,避免与原有数据重复/冲突,适合全量恢复(目标集合应为空或需替换)。--nsInclude/--nsExclude:指定要恢复或排除的命名空间(库.集合),用于选择性恢复,如只恢复某些集合或跳过某些集合,适合部分恢复。--restoreDbUsersAndRoles:恢复数据库的用户与角色(需 dump 时含用户信息),用于恢复访问控制,适合迁移/恢复用户权限。选择:全量替换用 --drop,选择性恢复用 --nsInclude/--nsExclude,恢复权限用 --restoreDbUsersAndRoles。

mongorestore 选项是"恢复范围与方式"的控制。理解 --drop 替换、--nsInclude/Exclude 选择性、--restoreDbUsersAndRoles 权限,是设计恢复策略的关键。按恢复需求选择选项,避免数据重复或权限丢失。

#
★★

11. Read Concern 的级别,local、available、majority、linearizable?

请说明 Read Concern 的级别:local、available、majority、linearizable?

  • local:读取本地节点数据
  • majority:多数派已提交
  • linearizable:线性一致,读主节点

Read Concern 的级别决定读取数据的可见性与一致性。local:读取本地节点当前可见的数据(可能未提交/未复制到多数派),速度快,一致性弱;available:类似 local 但更适合分片集群,返回本地可用数据,不等待多数派;majority:只读多数派已提交的数据,避免读到可能回滚的数据,一致性较强但需等待;linearizable:最强的线性一致,读操作路由到主节点并等待多数派确认,保证读到是"最新已提交"且之后不会回滚,但延迟最高、必须路由主节点。选择:需强一致用 majority/linearizable,追求性能用 local/available。linearizable 适合需要强一致读的场景(如余额、状态)。

Read Concern 由弱到强是 local/available → majority → linearizable。理解"local 快但可能不一致、majority 强一致、linearizable 线性一致但慢",是回答的关键。API 场景用 strong 读(majority/linearizable),性能场景用 weak。按一致性需求选择。

#
★★

12. Write Concern 的级别,w、j、wtimeout?

请说明 Write Concern 的级别:w、j、wtimeout?

  • w:需多少节点确认
  • j:是否写 journal
  • wtimeout:等待确认的超时时间

Write Concern 控制写入的确认与持久化强度。w:指定需多少节点确认写入(w:1 本节点、w:majority 多数派、w:N 指定 N 个节点),w 越大确认越强但延迟越高;j:指定是否要求数据已写 journal(j:true 需落 journal 才确认,防崩溃丢数据,j:false 不要求);wtimeout:指定等待确认的超时时间,超过则返回错误(即使 w 未满足),避免无限等待。三者组合定义写入的持久性与可用性:w:majority + j:true 提供强持久,w:1 + j:false 最快但 RPO 大。运维按 RPO 与性能要求配置 w、j、wtimeout。

Write Concern 的 w 控"多少节点确认"、j 控"journal 持久化"、wtimeout 控"等待超时"。理解三者的语义与组合,是配置写入持久化的关键。w:majority 提供强一致,j:true 防崩溃丢失,wtimeout 防无限等待。按 RPO 需求选择。

#
★★

13. 副本集故障转移的触发条件与选举时长(election timeout),应用如何处理 “not primary” 错误并重试?primary 网络分区时的只读行为如何配置?

请说明副本集故障转移的触发条件与选举时长,应用如何处理 "not primary" 错误并重试,以及 primary 网络分区时的只读行为如何配置?

  • 故障转移触发:primary 失联超过选举超时
  • 选举时长与无主窗口
  • 应用处理 not primary 错误并重试

副本集故障转移在 primary 失联(崩溃、网络分区)超过选举超时(默认 10 秒)后触发,secondary 发起选举,多数派投票产生新 primary,选举时长约几十秒(含检测与投票)。应用处理 "not primary" 错误:当写入打到旧 primary 失败时,应用应捕获该错误,从副本集发现新 primary(或重试连接),并重试写入;写入需具备幂等性以安全重试。primary 网络分区时的只读行为:当 primary 处于少数派分区时,它仍可能接受读(readPreference 默认 primary 读),但写入会失败;可通过配置 readPreference 让应用在分区时读 secondary,保证读可用。配置上,用多数派与 readPreference 控制分区时的读写行为。

故障转移的核心是"选举超时触发 + 多数派选举 + 应用重试"。理解"not primary 错误需重试 + 幂等"与"primary 分区时读 secondary 的配置",是回答的关键。选举时长决定 RTO,应用重试保证可用性。分区的读写行为由 readPreference 与多数派控制。

#
★★

14. 因果一致性会话(Causal Consistency)?

请说明 MongoDB 的因果一致性会话(Causal Consistency)?

  • 因果一致性:保证因果相关操作按顺序读取
  • 基于会话与操作时间戳(clusterTime)
  • 读支持因果链

因果一致性会话(Causal Consistency)是 MongoDB 提供的会话级一致性保证:在同一个会话内,如果操作 A 与操作 B 有因果依赖(A 导致 B 或 A 发生于 B 之前),则保证 B 能读到 A 的结果。实现基于会话与操作时间戳(clusterTime):会话内每个操作记录其在集群中的时间戳,后续操作携带该时间戳,确保读取/写入发生在该时间戳之后,从而在副本集/分片集群中维持因果顺序。因果一致性比强一致弱、比最终一致强,适合"读己之写"、会话内顺序操作等场景,且不要求 majority 读。它允许在会话内跨节点保证因果顺序,同时保持较高性能。

因果一致性是"会话级因果顺序保证"。理解"基于 clusterTime 时间戳 + 会话内因果顺序",是回答的关键。它满足"读己之写"与因果链,比最终一致强、比强一致轻量。适合需要会话内顺序一致的场景。

#
★★

15. compact 命令如何回收 WiredTiger 磁盘空间?为什么它会阻塞该集合、应如何在维护窗口或滚动执行?

请说明 compact 命令如何回收 WiredTiger 磁盘空间,为何阻塞该集合,以及如何在维护窗口或滚动执行?

  • compact 重写数据文件,回收空白空间
  • compact 阻塞该集合的读写
  • 维护窗口或滚动执行

compact 命令用于回收 WiredTiger 集合的磁盘空间。它通过重写集合的数据文件,把碎片与空白页合并,释放被删除/更新文档留下的空闲空间,返回磁盘空间给操作系统。为什么阻塞:compact 在重写数据文件时会锁定该集合,期间该集合的读写被阻塞(写入及读取都等待),因此不能在高并发环境下随意执行。执行策略:在维护窗口(低峰期)执行,避开业务高峰;或滚动执行——在副本集上对每个 secondary 逐个 compact,再对 primary 在维护窗口执行,避免一次性阻塞所有节点。compact 后需评估空间回收效果,并关注执行期间的资源占用。

compact 的本质是"重写文件回收空间,但阻塞集合"。理解"重写文件 + 阻塞读写 + 维护窗口/滚动执行",是管理磁盘空间的关键。应在低峰执行,副本集可滚动到 secondary 减少影响。compact 不适用于所有空间问题,需评估。

#
★★

16. WiredTiger 快照读的实现?

请说明 WiredTiger 快照读的实现机制?

  • 快照读基于 MVCC,读取一致版本
  • 快照记录事务提交时间点
  • 读不阻塞写

WiredTiger 的快照读基于 MVCC 实现。当一次读操作开始时,WiredTiger 确定一个快照(记录当前已提交事务的时间点),读取数据时基于该快照,返回快照时刻已提交的版本,不看到之后提交或未提交的修改。实现上,数据维护多个版本(版本链),每个版本带时间戳,快照读按时间戳选择对应版本。快照读不需要锁,读操作不阻塞写,写操作也不阻塞读(写通过文档级锁控制写写冲突)。快照读保证了读操作的一致性(可重复读)与并发性。事务的读也基于快照,实现事务内一致读取。

快照读的核心是"MVCC 版本 + 时间戳选择一致版本 + 无锁读"。理解"读基于快照时间点、不阻塞写、版本链维护多版本",是回答的关键。快照读保证读一致性与高并发。事务的读同样基于快照隔离。

#
★★

17. MongoDB 在线备份的工程化,如何组合文件系统快照与 oplog 归档降低 RPO,并定期做恢复演练验证备份可恢复?

请说明 MongoDB 在线备份的工程化,如何组合文件系统快照与 oplog 归档降低 RPO,以及定期做恢复演练验证备份可恢复?

  • 文件系统快照 + oplog 归档降低 RPO
  • 定期恢复演练验证可恢复性
  • 备份策略与监控

MongoDB 在线备份的工程化核心是"组合快照与 oplog 归档以降低 RPO"。文件系统快照提供某时刻的一致性备份,但 RPO 受快照频率限制;oplog 归档(持续采集 oplog)可以补全快照之后到故障时刻的变更,把 RPO 降到近零(秒级)。实现:定期做快照(如每天),同时持续归档 oplog(如 Debezium 或 oplog 采集),恢复时从最近快照恢复 + 回放 oplog 到故障时间点,实现近实时的 RPO。此外,必须定期做恢复演练:在测试环境验证备份可恢复、时间点恢复正确、数据完整,发现备份问题并及时修正。同时监控备份成功/失败、oplog 归档的连续性。工程化 = 快照+oplog 降 RPO + 定期演练验证 + 监控告警。

在线备份的工程化是"快照 + oplog 组合降 RPO + 恢复演练验证"。理解"快照提供基线、oplog 补全到近实时、演练验证可恢复",是设计备份体系的关键。RPO 越低越好,但需成本与复杂度。恢复演练是备份有效性的保障。

#

18. MongoDB 的读偏好(readPreference)与标签集(tag sets),如何把报表查询路由到指定 secondary?

请说明 MongoDB 的读偏好(readPreference)与标签集(tag sets),以及如何把报表查询路由到指定 secondary?

  • readPreference 决定读哪个节点(primary/secondary/nearest)
  • tag sets 用标签匹配节点
  • 报表查询路由到指定 secondary

readPreference 决定读操作路由到哪个节点:primary(默认,只读主)、primaryPreferred(优先主,不可用读从)、secondary(只读从)、secondaryPreferred(优先从,不可用读主)、nearest(就近)。标签集(tag sets)允许给节点打标签(如 region、purpose),配合 readPreference 精确路由到满足标签的节点。报表查询路由到指定 secondary:给报表节点打标签(如 {purpose: "report"}),设置 readPreference: secondaryPreferred 并指定 tag set {purpose: "report"},则报表查询路由到带该标签的 secondary,避免影响主库,同时利用从节点分担报表压力。这样实现按用途路由读流量。

readPreference 控"读哪类节点",tag sets 控"读哪些节点"。理解"readPreference 类型 + tag sets 标签匹配",是路由读流量的关键。报表查询路由到打标 secondary,既分流又隔离。按业务需求配置读偏好。

#

19. linearizable 读关注如何实现(读主节点并等待多数派确认)?为什么比 majority 更慢且要求路由到主节点?

请说明 linearizable 读关注如何实现(读主节点并等待多数派确认),以及为何比 majority 更慢且要求路由到主节点?

  • linearizable 读路由到主节点
  • 主节点确认该读操作发生在多数派之后
  • 比 majority 慢且必须主节点

linearizable 读关注提供最强的线性一致读:读操作必须路由到主节点(primary),主节点保证该读发生在其所有已提交写入之后,并向多数派确认该读操作,确保读到的数据是"最新已提交且之后不会回滚"的数据。实现上,主节点把读操作纳入 oplog 并等待多数派确认,因此读到的结果与其他线性一致操作一致。为什么比 majority 慢:linearizable 需要主节点对读操作做多数派确认(写入 oplog 并等待),而 majority 只需读多数派已提交快照,无需对读操作确认,因此 linearizable 延迟更高。为什么要求路由到主节点:只有主节点能保证读操作与写入顺序一致并纳入 oplog,secondary 无法保证线性一致,因此 linearizable 必须读主节点。

linearizable 的核心是"读主节点 + 多数派确认读操作"。理解"主节点把读纳入 oplog 并等待多数派"与"为什么必须主节点"是回答的关键。linearizable 比 majority 慢因为它对读操作也做多数派确认。它适合强一致读场景(余额、状态),接受延迟。