主题
MongoDB 生产检查清单
适用 MongoDB 6.0+(事务自 4.0/4.2 起,Change Streams 自 3.6 起);Atlas 向量检索条目单独标注。每条都可勾选,括号内是默认值或判断依据;版本差异以官方文档为准。 这份清单只列「不做会出事」的动作,机制解释见各篇正文。
上线前
- [ ] 副本集拓扑:3 个数据节点(P+2S)跨可用区;Arbiter 不存数据、不能备份,不能用它替代第二个数据节点。
- [ ] 写关注不丢数据:核心集合
writeConcern:{w:"majority", j:true, wtimeout:5000}(5.0+ PSS 默认已是majority,PSA 拓扑才退化为w:1;先用getWriteConcern()确认);核心读配readConcern:"majority",报表才走 secondary。 - [ ] oplog 留够:
oplogSizeMB至少为磁盘 10% 且 ≥10GB(Linux 默认约 5%、最少 990MB,以官方文档为准);按「写入速率×最长断连×2」复核,rs.printSecondaryReplicationInfo()的 lag>30s 告警。 - [ ] 分片键验证过:用真实量级数据 bulk insert + 主查询
explain验证各 shard 写入均匀、查询只路由单分片;分片键要基数高、非单调递增、覆盖主要查询。选错后 4.4+ 可refineCollectionShardKey追加后缀,5.0+ 可reshardCollection整体更换,但都有额外存储和切换成本。 - [ ] 文档与索引门禁:单文档 ≤16MB、嵌套 ≤100 层,会无限增长的数组用引用或 Subset(只嵌最近 N 条);索引按 ESR(Equal→Sort→Range),单集合索引 ≤64 个。
- [ ] 事务边界:单事务 ≤60 秒(
transactionLifetimeLimitSeconds默认 60);没有「1000 个文档」的硬限制,但单条 oplog entry ≤16MB;4.4+ 事务内可创建集合/索引(跨分片写事务除外);跨分片事务只用于必须原子的少量写。 - [ ] Change Stream 可续读:每个消费者持久化 resume token,oplog 窗口覆盖最长消费中断;5.0+ 用
startAfter提高 token 过期容忍度。 - [ ] AI 检索落地:
$vectorSearch是 Atlas 能力(自建 8.2+ 需额外部署 mongot);filter用到的 tenantId/docId 必须写进向量索引 mappings;numCandidates从 10–20×limit 起调。
运行中
- [ ] 复制与缓存:
rs.printSecondaryReplicationInfo()看 lag,rs.status()看 heartbeat 与节点 state;db.serverStatus().wiredTiger.cache看 used/max 与 eviction 次数,cache 打满先查全表扫描。 - [ ] 运行中查询:
db.currentOp()抓运行超过 100ms 的操作和 COLLSCAN;system.profile(profiler 默认slowms=100)按集合聚合慢查询;同时看索引数与avgObjSize趋势。 - [ ] 分片均衡:
sh.status()看 chunk 分布与 balancer 窗口;chunk 数差异超过 8 会触发迁移,迁移会同时压网络和目标 shard。
故障时
- [ ] 主节点宕机丢最近几秒写入 →
db.<集合>.getWriteConcern()→ 是w:1或 PSA 拓扑的退化默认 → 核心集合改w:"majority", j:true。 - [ ] 某 shard 负载是其他 10 倍 →
sh.status()看 chunk 分布 + 分片键取值 → 分片键单调递增或基数过低 → 只能按新键重建并迁移。 - [ ] 从节点长期 RECOVERING 或 Change Stream 报 token not found →
rs.printSecondaryReplicationInfo()的 lag + oplog 时间窗 → oplog 已被覆盖 → 调大oplogSizeMB后重新同步/全量重灌。 - [ ] 查询突然全慢、连简单查询也慢 →
db.currentOp()抓 COLLSCAN → 扫描把 WiredTiger Cache 挤掉 → 加索引并 kill 长扫描。