Skip to content

全量同步时序集合适配不足:强制 _id 排序导致源端大量落盘,且目标端未按时序属性创建 #993

Description

@zhongli-james

背景

关联 issue #992。用户全量同步大体量时序集合(单表逻辑数据 ~226GB、压缩后 ~50GB)时,源端出现 (OutOfDiskSpace) PlanExecutor error during aggregation :: Available space ... less than the required minimum of 524288000 bytes,并伴随大量 E11000 duplicate key error ... index:_id_。排查后确认磁盘触底是被 MongoShake 的全量读行为放大,而 dup则指向目标集合未被建成时序集合。当前全量链路把时序集合当普通集合处理,存在多处适配不足。

根因(均已在代码确认)

影响

建议方案(分阶段)

Phase 1 —— 快速止血,低风险:

  • 全量读时序集合时不设置 _id 排序(改为自然顺序扫描)。全量同步不依赖 _id 有序,自然顺序即可消除服务端阻塞排序与落盘。
  • 时序集合强制 full_sync.reader.parallel_thread=1(splitVector 依赖索引,TS 无 _id 索引不适用并发分片读)。
  • 在文档/日志中提示:大体量时序全量对源端读节点(注意 secondaryPreferred 命中的是从节点)有临时空间要求。

Phase 2 —— 正确性适配,后续跟进:

  • 全量开始前,若目标端不存在,按源端 timeseries选项(timeField/metaField/granularity/expireAfterSeconds)创建时序集合,避免被降级为普通集合。
  • 评估对时序集合改为直接读写 system.buckets.*(bucket 天然有 _id,可廉价扫描/排序,写入保留原 bucket 结构),与增量链路已有的system.buckets 处理保持一致,实现忠实复制。
  • 时序目标集合不使用按 _id 的 insert_on_dup_update 兜底;改为「保证目标干净 + 单趟不中断」或基于 bucket 幂等的策略。

验证建议

  • 大体量时序集合全量:对比开启/关闭 _id 排序时源端读节点 dbPath/_tmp 落盘峰值与耗时。
  • 预存时序集合 sync_mode=all:确认目标端被建成时序集合(db.getCollectionInfos 含 timeseries),且无 id 索引、无 E11000。
  • 崩溃重启重跑:确认时序集合重放不因 dup 兜底失败而 panic。

相关:#992#897#784

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions