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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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