reshardcollection 会因三路 i/o 并发、写放大及 oplog 不可控增长导致磁盘空间数小时内迅速耗尽,需提前扩容 oplog 并实时监控 oplog 大小与使用率。

reshardCollection 会触发大量随机写 + oplog 爆涨,不调大 oplogSize 或清理旧数据,磁盘可能在 24 小时内被打满。
reshardCollection 期间磁盘空间为何突然飙升
reshardCollection 不是覆盖写,而是“边读旧 chunk、边写新分片、边记 oplog”,三路 I/O 并发打在同一块盘上。尤其当集合含大量小文档(如 IoT 事件、日志),WiredTiger 压缩率低,实际写入量可达原始 storageSize 的 1.8–2.5 倍。常见现象包括:
- 监控图中
disk_write_bytes_per_sec突增 3–5 倍,且持续数小时 -
df -h显示磁盘使用率每小时涨 5%–10%,远超日常增长曲线 - mongod 日志出现
WT_ERROR: filesystem full或write error: No space left on device
oplog 保留策略没调,resharding 一启动就爆盘
MongoDB 默认 oplog 大小为磁盘容量的 5%(最小 990MB),但 resharing 过程中每个迁移操作都会生成对应 oplog 条目——不是一条 update,而是多条:chunk 拆分、元数据更新、新索引创建、config server 同步等。若原 oplog 只有 2GB,而 resharing 产生 3.2GB oplog 条目,WiredTiger 会先写满 oplog 盘,再触发强制 compact,进一步加剧 I/O 压力。
实操建议:
- 执行
reshardCollection前,用rs.printReplicationInfo()查当前 oplog 大小和保留时长;确保保留窗口 ≥ 预估 resharing 总耗时 × 1.5(例如预计 6 小时,则至少保留 9 小时) - 扩容 oplog:停机修改
storage.oplogSizeMB(如设为 10240),或在线执行db.runCommand({ replSetResizeOplog: 1, size: 10240 })(仅 4.4+ 支持) - 禁止在 resharing 期间执行
db.getSiblingDB("local").oplog.rs.drop()—— 这会导致主从同步断裂
监控必须盯住这三个指标,否则等告警就晚了
resharding 不是后台静默任务,它会直接冲击磁盘水位线。以下三个指标需设置 5 分钟粒度监控:
-
db.serverStatus().metrics.record.repl.oplogSizeMB:当前 oplog 实际占用大小(不是配置值) -
db.getSiblingDB("local").oplog.rs.stats().size:oplog 集合物理大小(单位字节),比前者更真实 -
db.adminCommand({ getCmdLineOpts: 1 }).parsed.storage.oplogSizeMB:确认配置已生效,避免参数未加载
只要 oplog.rs.stats().size 超过 oplogSizeMB × 0.85,立刻触发扩容流程;若已超 0.95,resharding 必须暂停,先清理旧备份或归档历史日志。
resharding 的磁盘压力本质是「写放大 + oplog 不可控增长」叠加的结果,很多团队只盯着 storageSize 留 1.2 倍空间,却忘了 oplog 是独立文件系统路径、且默认不压缩。没配好 oplog 策略的 resharing,就像开着油箱盖开车——跑得越快,漏得越狠。











