MongoDB 4.2+ 默认启用 Hybrid Index Build 实现在线建索引,无需 background: true;其分两阶段构建索引结构与异步填充数据,依赖 WiredTiger 快照,要求版本≥4.2、FCV≥4.2、引擎为 WiredTiger 且不在 secondary 执行。

MongoDB 4.2+ 默认就是在线建索引,不需要额外配置——但前提是别用 background: true。 它底层已切换为 Hybrid Index Build(混合构建),在主节点上边服务边建索引,不阻塞写入;从节点则通过 oplog 异步回放索引操作。不过这个“在线”有隐含前提,一不小心就会退化成阻塞式构建。
Hybrid Index Build 是什么,和老版本 background 有什么区别?
Hybrid Index Build 不是新命令,而是 MongoDB 内部对 createIndex() 的默认执行模式:它把索引构建拆成两个阶段——先建好索引结构并允许写入继续,再异步填充已有文档数据(通过 snapshot + oplog 回放)。而老版本的 background: true 是 fork 子进程、扫描全表、全程不锁集合写入但会显著拖慢读写性能;更早的 foreground 模式则直接全局写锁。
关键差异在于:
-
background: true在 4.2+ 已被标记为 deprecated,且启用后会禁用 Hybrid 构建,强制走旧路径 - Hybrid 构建依赖 WiredTiger 快照机制,因此要求集合使用
wiredTiger引擎(MMAPv1 不支持) - 构建期间主节点仍可接受写请求,但索引字段的查询结果可能暂时不完整(直到构建完成并完成 initial sync)
如何确保真正触发 Hybrid Index Build?
只要满足以下全部条件,createIndex() 就自动启用 Hybrid 模式:
- 运行版本 ≥ 4.2,且
featureCompatibilityVersion已设为"4.2"或更高(用db.adminCommand({getFeatureCompatibilityVersion: 1})确认) - 未显式传入
background: true——哪怕写成{background: false}都没问题,但带true就会绕过 Hybrid - 集合存储引擎是
wiredTiger(db.getCollectionInfos({name: "your_col"})查options.storageEngine) - 不是在 replica set 的 secondary 节点上执行(secondary 上执行
createIndex()会被拒绝)
示例正确调用:
db.users.createIndex({ email: 1 }, { unique: true, name: "email_1" })
错误示范(会退化):
db.users.createIndex({ email: 1 }, { background: true }) // ❌ 触发旧 background 模式
建索引时容易卡住或变慢的几个现实坑
Hybrid 模式虽不锁写,但仍有资源瓶颈和行为陷阱:
- 如果集合数据量极大(比如 >100GB),构建第二阶段(填充历史文档)可能持续数小时,期间
db.currentOp()里会看到"type": "indexBuild"状态,但"secs_running"不代表阻塞时间,而是总耗时 - WiredTiger cache 不足时,构建过程会频繁刷盘,导致 I/O 打满;建议提前检查
db.serverStatus().wiredTiger.cache中的"bytes currently in the cache"是否接近上限 - 如果建索引期间发生 primary 切换,新 primary 会中止当前构建并从头开始——所以高可用集群中尽量避开故障窗口期
-
collation或通配符索引({"$**": 1})也会启用 Hybrid,但构建开销更大,且通配符索引无法指定partialFilterExpression
Hybrid Index Build 的“在线”是相对的:它消除了写锁,但没消除资源竞争。真正决定是否影响业务的,是你集群当时的内存余量、磁盘吞吐和 oplog 延迟水位——这些比命令参数更值得盯紧。


















