升级后索引变慢、阻塞写入或失败,主因是4.2与5.0索引构建机制差异:4.2后台索引仍锁元数据、单线程扫描且不可恢复;5.0需显式设FCV="5.0"、全分片升级并首次创建才启用可恢复索引,否则降级执行。

升级后索引变慢、阻塞写入、甚至建索引失败,大概率不是配置错了,而是版本间索引构建机制发生了不可忽略的底层变化——4.2 和 5.0 的 createIndex 行为根本不在同一套逻辑里。
4.2 的“后台索引”其实仍会锁元数据,且不支持恢复
4.2 虽然取消了传统 foreground 模式,但它的所谓“优化后台构建”仅在开始和结束两个瞬间加排他锁(X lock),中间阶段用 IX 锁交替读写。这听起来友好,但实际有硬伤:
- 整个构建过程仍是单线程扫描集合,CPU 和 I/O 无法并行,大集合耗时长
- 若 mongod 崩溃或被 kill -9,索引直接回滚,必须重头再来
- 副本集上 secondary 节点靠 oplog 回放索引操作,期间若主节点执行
dropIndexes,会卡住 oplog 回放,导致从节点连接池耗尽 -
background: true在 4.2+ 已被废弃,传了也不生效;它现在是默认行为,但不等于“无感”
5.0 的可恢复索引要求 fCV 显式设为 "5.0",否则降级走 4.4 路径
5.0 引入的「可恢复索引创建」不是开箱即用的功能,它依赖新的元数据格式和检查点机制,必须满足三个硬性条件才生效:
- 运行
db.adminCommand({setFeatureCompatibilityVersion: "5.0"}),否则即使二进制是 5.0,createIndex仍按 4.4 规则执行 - 索引必须是首次在 fCV="5.0" 状态下创建(或重建),4.4 时代已存在的集合上新建索引,不会自动获得恢复能力
- 分片集群中所有 shard 必须完成 FCV 升级,否则
createIndex请求落到旧 shard 上,恢复逻辑失效
典型错误:升级完 mongos 和 config server,忘了逐个登录每个 shard 执行 FCV 设置,结果建索引时一半节点恢复、一半从头跑。
唯一索引在 4.2→5.0 升级后可能隐性失效
4.2 起 MongoDB 对唯一索引启用了新内部格式,与 4.0/3.6 不兼容。升级后若未重建旧唯一索引,会出现两种风险:
- 某些边界 case 下(如含数组字段的唯一复合索引),查询计划可能跳过索引,或唯一性校验漏触发
- 如果原集合在 4.0 创建过唯一索引,升级到 5.0 后未显式
collMod或drop+create,该索引仍用旧格式存储,无法享受 5.0 的并发校验优化 - 副本集滚动建唯一索引时,5.0 要求全程停写;而 4.2 允许边建边写(但冲突写入会被拒绝),误以为“升级后更稳”,实则约束更严
别只盯着“能不能建”,先看 writeConcern 和排序是否被连带影响
5.0 默认 writeConcern 从 {w: 1} 改为 {w: "majority"},这会拖慢所有写操作——包括索引构建过程中产生的 side-write 日志落盘速度。同时,5.0 虽支持磁盘排序,但若查询带 $sort 却没命中索引,依然可能触发 Sort operation used more than the maximum 33554432 bytes of RAM 错误,尤其当索引字段顺序与 sort 字段不一致时。
真正要检查的不是索引建没建好,而是:explain("executionStats") 里 stage 是否为 IXSCAN 而非 SORT,executionTimeMillis 是否稳定,以及 totalDocsExamined 是否远大于 totalKeysExamined——后者说明索引没被有效利用。


















