Skip to content

fix(collector): orphan segment recovery stalls startup unboundedly (usdm 3-day outage root cause) #552

Description

@proerror77

Change contract

binance-lob-archiver startup/rotation recovery must not be able to stall indefinitely on a large orphan .part / interrupted .zst.tmp: bounded memory, visible progress, application logging, and a deterministic quarantine-or-finalize decision.

Production incident (2026-07-28 → 2026-07-31, usdm)

  • Rotation at 2026-07-28 17:00 UTC began compressing a 4.5GB .part; the process was throttled into D-state by cgroup memory.high (2500M) mid-compression and never finished.
  • Every restart for 3 days re-read the orphan .part before opening any WS connection: observed fd pinned on the file, read_bytes growing ~840KB/s under throttle, zero network connections, RSS climbing past 3.2GB, zero application log lines, no segment production.
  • Result: no usdm data 2026-07-28 17:00 → 2026-07-31 22:10. Resolved operationally by quarantining the orphan (preserved at /data/monday/spool/quarantine/binance-lob-usdm-20260728t17/) and restarting; service then bridged all 573 symbols in ~4 min at 85MB RSS.

Defects to fix (ranked)

  1. Recovery path re-reads/parses arbitrarily large orphan segments with unbounded memory and no progress visibility (no logs at all — RUST_LOG=info produces zero journal lines; verify a tracing subscriber is actually initialized).
  2. Count-based buffers with byte-unbounded elements: 250k-event channel × (full Value frame + parsed copy) + 250k global pending diffs ≈ multiple GB (binance-lob-archiver.rs:822, lob_archiver.rs:114-139). Make budgets byte-based or drop raw frames after parsing.
  3. Rotation-time memory peak (checkpoint serialization of full catalog + zstd) vs cgroup limits needs a documented envelope; the original 07-28 stall happened here.

Acceptance

  • Application logs visible in journal (subscriber init fixed), incl. recovery progress
  • Recovery of a 4.5GB orphan completes or quarantines deterministically within bounded memory (test with a large synthetic orphan)
  • Buffer budgets byte-aware or per-element bounded; tests prove envelope
  • Orphaned 07-28 segment (quarantined on host) is finalized and uploaded, or explicitly declared lost in the data-quality log

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingready-for-humanHuman implementation or judgment is requiredruntimeRequires deployment, runtime mutation, or live evidence for closure

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions