MongoDB 4.4 同步建索引不提升速度,仅允许构建期间继续读写(不违反约束),底层仍单线程扫描,宕机即回滚;5.0 升级为可恢复索引创建,支持检查点续建,需 fCV 设为 "5.0"。

createIndex 在 4.4 中默认启用的同步建索引(Simultaneous Indexing)机制。
同步建索引 ≠ 异步或后台建索引
很多人误以为 4.4 的“同步”是并发加速,其实它只是允许写操作与索引构建并行执行,前提是不违反约束(比如唯一索引插入重复值会被拒绝)。底层仍是单线程遍历集合+构建 B 树,I/O 压力未降低,甚至可能因读写混杂加剧随机 IO。
-
background: true依然存在,但 4.4 默认不依赖它;createIndex({a:1})直接就是同步模式 - 非唯一索引下,插入/更新基本无感知;唯一索引需实时校验,可能增加写延迟
- 若构建中 mongod 崩溃,整个索引回滚,必须重来——没有检查点,不可恢复
为什么有人觉得“变快了”?
错觉往往来自业务侧:以前用 background: true 构建时,虽然不阻塞写,但查询计划器可能选错索引(尤其有同名字段多个索引时),导致慢查;而 4.4 同步构建完成后索引立即可用、状态明确,配合 explain("executionStats") 更容易确认是否命中,主观上“见效更快”。
- 检查是否走索引:
db.collection.find({a:1}).explain("executionStats"),看"stage"是"IXSCAN"还是"COLLSCAN" - 注意
"totalDocsExamined"接近"nReturned"才算高效;若远大于,说明索引未生效或选择性差 - 隐藏索引(
collMod+hidden: true)可临时禁用旧索引做对比,避免误删
IO 压力根本没降,但可以缓解
B 树索引构建本质是顺序读集合 + 随机写索引页,4.4 没改变这个模式。所谓“降低 IO 压力”,只能靠外部手段:
- 确保
wiredTigerCacheSizeGB足够大,让索引页尽量留在内存,减少刷盘 - 建索引前用
db.collection.stats()看"size"和"avgObjSize",预估索引体积;超内存时考虑分批建(如按时间范围拆集合) - 避免在高写入峰值期建索引;副本集建议先在 secondary 上建(需
rs.secondaryOk()+db.getMongo().setReadPref("secondary")),再切 primary
"5.0",否则 4.4 的同步构建只是把“停服等待”换成了“边跑边建”,IO 负载一点没少。


















