Visitar URL original
fix(buffers): make disk buffer record reads cancel-safe by wafgo · Pull Request #27163 · vectordotdev/vector · GitHub
Skip to content

fix(buffers): make disk buffer record reads cancel-safe - #27163

Open
wafgo wants to merge 1 commit into
vectordotdev:masterfrom
wafgo:fix/disk-buffer-cancel-safe-reads
Open

wafgo wants to merge 1 commit into
vectordotdev:masterfrom
wafgo:fix/disk-buffer-cancel-safe-reads

Conversation

@wafgo

@wafgo wafgo commented Nov 13, 2026

Copy link
Copy Markdown

Summary

A memory buffer with when_full: overflow into a disk buffer never drains the disk stage while the memory stage keeps receiving events. Spilled events stay on disk until a restart, or are never delivered.

BufferReceiver::next polls the disk reader inside select! against the memory stage and drops the disk read future whenever the memory stage wins. RecordReader::try_next_record is not cancel-safe: it reads the length delimiter, then fills aligned_buf over several fill_buf/consume calls. When the future is dropped in between, the bytes already consumed are gone, and the next call reads the middle of a record as a length delimiter. The reader then fails on garbage or waits for data that never arrives.

This PR keeps the length of the record being collected in pending_record_len, so a cancelled try_next_record resumes the same record instead of starting over. The buffer is reset only when a new record starts, and the pending state is cleared on errors and once the record is complete.

References

Closes: #20322
Related: #24304
Related: #26033 (touches the same reader; it does not change record-read cancellation, so the two should compose)

Vector configuration

sinks:
  influx:
    type: influxdb_logs
    # ...
    buffer:
      - type: memory
        max_events: 2000
        when_full: overflow
      - type: disk
        max_size: 268435488
        when_full: drop_newest

How did you test this PR?

  • New test overflow_disk_stage_drains_while_memory_stage_is_live in topology/channel/tests.rs: spills records to the disk stage, then keeps the memory stage live and asserts that every spilled record is delivered without recreating the buffer. It fails on master and passes with this change.
  • cargo test -p vector-buffers passes. known_errors::writer_detects_when_last_record_has_scrambled_archive_data is flaky with and without this change.
  • On an aarch64 edge device (0.57.0 with this patch, ~29 events/s per sink, two InfluxDB sinks), the outbound traffic was blocked with iptables:
    • Stock 0.57.0: the memory stage filled to 2000 and the disk stage to ~2500. After unblocking, the memory stage drained immediately, but the disk stage stayed at ~1700 events for the full 5 min observation while live events kept flowing.
    • Patched: same outage (5 min, disk stage ~5500). Both stages were at 0 within 10 s after unblocking, without a restart. Every event arrived and the series in InfluxDB has no gap.
    • Patched, systemctl restart vector in the middle of the outage: the disk stage contents survived the restart and were delivered after unblocking.
    • Restarting the stock instance on the patched build drained its stuck disk stage within a minute.

Does this PR include user facing changes?

  • Yes. Please add a changelog fragment based on our guidelines.
  • No. A maintainer will apply the no-changelog label to this PR.

The memory -> disk overflow receiver polls the disk reader inside select!
against the memory stage. A record larger than the reader's 256 KiB read
buffer needs several fill_buf calls; cancelling the read between them lost
the bytes already consumed, so the reader resynchronised on garbage and the
overflow stage was never drained while the memory stage stayed live.

Ref: vectordotdev#20322
@wafgo
wafgo requested a review from a team as a code owner November 13, 2026 11:45
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-13T11:49:29.395854Z 2597d35 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Before we can merge this PR, please sign our Contributor License Agreement.

To sign, copy and post the phrase below as a new comment on this PR.

Note: If the bot says your username was not found, the email used in your git commit may not be linked to your GitHub account. Fix this at github.com/settings/emails, then comment recheck to retry.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@datadoghq-integration datadoghq-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bits Code Review: PASS

More details

Interrupted disk reads preserve the record length and accumulated payload, allowing subsequent polls to resume the same record without losing its boundary when memory-stage traffic wins.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Bits Code Review · Commit 2597d35

This branch has not been deployed

No deployments
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.

Tiered buffers on overflow two bugs

1 participant