知其然,知其所以然
MongoDB 2026-10-12

arbiter 与 w:majority 的陷阱

实测 arbiter 与 w:majority 的陷阱:PSA 结构里停掉唯一的 secondary 后 primary 仍是 primary,w:1 与默认写关注(隐式 w:1)成功,w:majority 超时(code 64);majority 读看不到新写入,多数提交点停住且落后越拉越大(5 到 9 秒);恢复后追平;PSS 停一个 secondary 则 w:majority 不受影响。

MongoDB arbiter 仲裁节点 w:majority PSA 副本集 真实验证 动画演示
MongoDB 2026-10-12

hidden 与 delayed 成员

实测 hidden 与 delayed 成员:hidden 成员不出现在 hello.hosts,secondary 读偏好 100 次一次也选不到,但照常复制可直连读;延迟 8 秒的成员 8.1 秒后才有新写入,drop 之后窗口内仍有数据可救回;延迟成员有投票权会让 w:majority 慢约 8 秒。

MongoDB hidden成员 delayed成员 secondaryDelaySecs 副本集 真实验证 动画演示
MongoDB 2026-10-12

stepDown:切主期间读写不可用多久

实测切主期间的不可用时间:replSetStepDown 优雅切主只有约 30 ms,客户端无错误;kill -9 primary 默认约 10.8 秒(electionTimeoutMillis 10 s),调成 4 s 后约 4.2 秒;w:majority 的确认写入一条未丢;切主期间 secondary 读不受影响,primary 读阻塞约 10 秒。

MongoDB stepDown 选举 故障切换 electionTimeoutMillis 副本集 真实验证 动画演示
MongoDB 2026-10-12

oplog 窗口:大小决定了落后多久还能追上

实测 oplog 窗口:getReplicationInfo 的窗口字段;不同写入每条 oplog 的大小(小更新 163 字节、1 KB 插入 1,142 字节、10 KB 插入 10,097 字节);按实测字节估算 128 MB 到 10 GB 的 oplog 在 1,000 次/秒负载下的窗口;size 与压缩后 storageSize;replSetResizeOplog 最小 990 MB;secondary 离线 15 秒后 2.8 秒追平。

MongoDB oplog oplog窗口 replSetResizeOplog secondary 副本集 真实验证 动画演示
MongoDB 2026-10-12

chunk 拆分与迁移:balancer 实际搬了什么

实测分片集群上 chunk 的拆分与迁移:空集合一个 chunk;写入触发分裂,balancer 同时把拆出的 chunk 迁到另一个分片;最终 chunk 个数 1 对 26 但数据量 31.1 MB 对 28.2 MB(按数据量平衡);迁走的数据以孤儿文档形式在源分片留 3600 秒;changelog 记录每次迁移的 6 个步骤;分片键全相同产生 jumbo chunk。

MongoDB 分片 chunk balancer moveChunk jumbo 孤儿文档 真实验证 动画演示
MongoDB 2026-10-12

单调递增的分片键:写入热点实测

实测单调递增分片键的写入热点:关掉 balancer 后 30 秒 287,500 次写入全部打在 sh0(100%),哈希键与手工打散的复合键各占 50%;开 balancer 后旧数据被搬走一部分(119,535 对 167,965),但新写入的 20,000 个更大键仍然全部落在 sh0;范围查询 ranged 只问 1 个分片,hashed 要问全部。

MongoDB 分片键 单调递增 写入热点 hashed balancer 真实验证 动画演示
MongoDB 2026-10-12

hashed 分片与 ranged 分片的 chunk 分布

实测哈希与 ranged 分片键的 chunk 分布:哈希键建集合时每个分片一个 chunk、连续键对半分(30,451 对 29,549),ranged 连续键 100% 在一个分片;随机键的 ranged 集合靠 balancer 分开;70% 文档同一个键值时哈希也救不了(85% 在一个 chunk);哈希键的等值查询 targeted,范围与 $in 多值 scatter-gather。

MongoDB 分片 hashed ranged chunk分布 热点键 真实验证 动画演示
MongoDB 2026-10-12

mongos 路由:targeted 与 scatter-gather

实测 mongos 路由:3 个分片上带分片键的等值/范围查询是 SINGLE_SHARD,跨段范围或 $in 多值或不含分片键是 SHARD_MERGE(问所有分片,各分片计数器各 +100);sort + limit 是 SHARD_MERGE_SORT,每个分片各返回 5 个再归并;9.0.2 上不带分片键的 update_one / delete_one 也能成功。

MongoDB mongos 路由 targeted scatter-gather 分片查询 真实验证 动画演示
MongoDB 2026-10-12

zone sharding

实测 zone sharding:给分片打 zone 标签并用 updateZoneKeyRange 声明键范围后,balancer 把 eu 的 8,000 个文档迁到 EU 分片、us 的留在 US 分片,没有 zone 的 apac 平均分到其它分片;chunk 在 zone 边界被切开;改 zone 后 us 的数据又跟着搬到新的分片。

MongoDB zone sharding 区域分片 addShardToZone updateZoneKeyRange 真实验证 动画演示
MongoDB 2026-10-12

分片集合上唯一索引的限制

实测分片集合上唯一索引的限制:非分片键的 unique 被拒(code 67);必须以分片键为前缀,但这样只保证同一个分片键值下唯一;_id 在分片键不是 _id 时可以在两个分片上重复;让唯一字段做分片键才能全局唯一;哈希分片键不能声明 unique(code 72),_id 哈希分片时 _id 实际全局唯一。

MongoDB 分片 唯一索引 shard key E11000 真实验证 动画演示
MongoDB 2026-10-12

分片集群上的聚合:merge 阶段在哪执行

实测 3 分片集群上聚合 pipeline 的拆分:带分片键条件只命中相关分片、无 splitPipeline;$group 拆成分片上的部分分组 + 合并阶段的 $mergeCursors/$group(每个分片扫描 10,000 个文档只返回 50 个);$sort+$limit 把 limit 并进分片排序;$lookup/$merge 在 mergerPart;$sort 放在 $group 前面时耗时从 3.9 ms 变成 18 ms。

MongoDB 分片 聚合 mergerPart shardsPart explain 真实验证 动画演示
MongoDB 2026-10-12

mongodump --oplog 与 mongorestore 的一致性

实测写入进行中的 mongodump:不带 --oplog 恢复后两个集合不在同一时间点(n − w = −623);--oplog 生成 oplog.bson(627 条 applyOps),--oplogReplay 重放 1254 个操作后 n == w;不带 --oplogReplay 恢复则 oplog.bson 被无提示忽略;--oplogLimit 取中间点会不一致;--oplog 只支持整库。

MongoDB mongodump mongorestore oplog 一致性 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号