Skip to content

feat(diag): persistent memory trajectory + query-leak CI soak (#581 observability)#675

Merged
DeusData merged 1 commit into
mainfrom
fix/581-leak-mitigation
Jun 28, 2026
Merged

feat(diag): persistent memory trajectory + query-leak CI soak (#581 observability)#675
DeusData merged 1 commit into
mainfrom
fix/581-leak-mitigation

Conversation

@DeusData

Copy link
Copy Markdown
Owner

Summary

Adds observability + a CI guard to find and prevent query-path memory leaks (#581), based on a diagnostic finding that the leak does NOT reproduce in our soak.

Diagnostic finding

A 10-minute, 200-file query-only soak (CBM_SOAK_MODE=query-leak) shows RSS flat-to-shrinking and committed memory plateauing. With mimalloc purge_delay=0 (mem.c), freed memory is already returned to the OS immediately. Speculative per-query collect/checkpoint mitigations are therefore not justified, and a WAL TRUNCATE is unsafe here (ftruncate can SIGBUS an mmap'd sibling, see store.c). So this PR ships observability to find the leak where it actually occurs, plus a continuous regression guard — not a speculative fix.

Changes

  • diag: the diagnostics writer appends a PERSISTENT NDJSON memory trajectory (one sample / 5s: rss, committed, peak fields, page_faults, fd, queries), kept on exit (rotates to a .1 generation past 8 MB). The prior latest-snapshot file was overwritten every 5s and deleted on stop, so users could never capture a trend.
  • ci: the soak now also runs a read-only query-leak leg on every platform incl. Windows, catching any regression that introduces a query-path leak. soak-test.sh RESULTS_DIR is env-overridable so both legs keep separate artifacts.
  • docs: README 'Troubleshooting & Diagnostics' + a bug-report field explain the no-telemetry stance and how users capture and share the trajectory.

Verification

  • Build clean; unit suite 5714 passed / 0 failed.
  • Trajectory verified to persist post-exit (34 samples across a 2-min soak).

#581 (query-path memory growth) does not reproduce in our soak: a 10-min,
200-file query-only run shows RSS flat-to-shrinking and committed plateauing
(mimalloc already purges on free, purge_delay=0). Rather than ship speculative
mitigations for a leak we cannot measure, this adds the observability to find it
where it actually occurs, plus a continuous guard.

- diag: the diagnostics writer now appends a PERSISTENT NDJSON memory trajectory
  (one sample / 5s: rss, committed, peak fields, page_faults, fd, queries), kept
  on exit (rotates to a .1 generation past 8 MB) so users can send the time
  series post-mortem. The previous latest-snapshot file was overwritten every 5s
  and deleted on stop.
- ci: the soak now also runs a read-only query-leak leg (CBM_SOAK_MODE query-leak,
  no reindex/mutate) on every platform including Windows, so a regression that
  introduces a query-path leak is caught. soak-test.sh RESULTS_DIR is now
  env-overridable so both legs keep separate artifacts.
- docs: README Troubleshooting and Diagnostics section + a bug-report field
  explain the no-telemetry stance and how to capture and share the trajectory.

Build clean; unit suite 5714/0; trajectory verified to persist post-exit.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant