Capped Collection 适合日志因固定大小、FIFO 覆盖、无删除开销,但易误用——不按时间/TTL清理、不支持索引TTL、最老文档无差别覆盖,需按吞吐反推容量并建timestamp索引。

用 Capped Collection 做日志存储,确实能省掉手动轮转和清理逻辑,但默认行为不等于开箱即用——它不会自动按时间或大小“智能翻滚”,而是靠固定容量+插入顺序 FIFO 覆盖,稍不注意就丢关键日志。
为什么 Capped Collection 适合日志,但又容易误用
Capped Collection 是 MongoDB 提供的预分配、固定大小、插入有序、自动覆盖的集合类型。它天然契合日志“只追加、查最新、过期即弃”的模式,避免了手动删旧文档带来的写锁、碎片和性能抖动。
但它不是“日志轮转服务”:不识别时间字段,不按 timestamp 删除,也不支持 TTL 索引(TTL 索引在 capped 集合上被禁用)。一旦空间满,最老文档被无条件覆盖——哪怕那条是 ERROR 级别且刚写入。
- 必须显式指定
size(字节)或max(文档数),二者不能同时设 - 创建后无法修改
size或max,只能drop重建 -
find()默认按插入顺序返回,但sort({$natural: -1})才能稳定拿到最新几条 - 不支持
$push到数组字段的原子更新(因空间不可变),日志文档需全量写入
创建 Capped Collection 的正确姿势(Shell + Driver)
关键不是“能不能建”,而是建的时候是否对齐真实日志吞吐与保留窗口。比如每秒写入 500 条、平均每条 1KB,则一小时需约 1.8GB;若只配 size: 100MB,不到 4 分钟就覆盖——根本来不及排查问题。
推荐按“保留最近 N 小时高水位写入量”反推 size,并留 20% 余量:
- Mongo Shell 创建(带
noPadding减少空间浪费):db.createCollection("app_logs", { capped: true, size: 2147483648, max: 1000000, noPadding: true }) - Python PyMongo 初始化(确保幂等):
db.create_collection("app_logs", capped=True, size=2_147_483_648, max=1_000_000, codec_options=CodecOptions(tz_aware=True)) - 务必在
timestamp字段上建索引(否则按时间范围查会全表扫描):db.app_logs.createIndex({ "timestamp": -1 })
查询日志时必须绕开的坑
Capped Collection 的物理顺序 ≠ 业务时间顺序。如果你依赖 timestamp 做分页或范围查询,仅靠自然顺序不够——尤其当应用本地时间不同步、或批量补录历史日志时,$natural 排序会把新时间戳的老日志排在前面。
- 查最近 100 条 ERROR 日志:
db.app_logs.find({ level: "ERROR" }).sort({ timestamp: -1 }).limit(100)—— 必须有timestamp索引支撑,否则慢得无法接受 - 分页查某时间段日志:
db.app_logs.find({ timestamp: { $gte: ISODate("2026-04-12T00:00:00Z"), $lt: ISODate("2026-04-13T00:00:00Z") } }).sort({ timestamp: -1 })—— 若没索引,explain("executionStats")会显示totalDocsExamined等于整个 capped 集合大小 - 不要用
skip()做分页:capped 集合无稳定 _id 递增保证,skip(10000)可能跳过实际存在的日志
真正需要“翻滚”时,得自己补一层控制逻辑
所谓“自动翻滚”,只是空间满了就覆盖——它不管内容重要性、不区分环境(dev/staging/prod)、也不联动告警。生产系统中,你大概率需要:
- 监控
db.runCommand({ collStats: "app_logs" })中的count和size,接近上限时触发告警 - 为不同日志级别设置不同集合(如
error_logs用更大size,debug_logs用小max),避免 INFO 淹没 ERROR - 在应用层写入前判断:若
level === "FATAL"且当前count> 95% 容量,同步发 Slack/Webhook 告警 - 定期归档(非 capped)到冷存储:用
mongodump --query导出指定时间范围,再mongorestore到 archive 库
最后提醒一句:Capped Collection 的优势在于“轻量、低开销、确定性行为”,而不是“全自动日志治理”。它的边界很清晰——管存储结构,不管业务语义。越想让它聪明,越得在它外面套一层清醒的逻辑。











