DD 7.3: Batch drain relocationComplete to prevent fetchKeysComplete OOM#12993
DD 7.3: Batch drain relocationComplete to prevent fetchKeysComplete OOM#12993saintstack wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a DDQueue event-loop starvation issue where relocationComplete processing can be delayed by other frequent events (e.g. dataTransferComplete), allowing fetchKeysComplete to grow without bound and potentially cause OOM. It refactors relocation-completion handling into a helper and batch-drains ready completion events to keep fetchKeysComplete bounded.
Changes:
- Extracted relocation completion bookkeeping into
DDQueue::processRelocationComplete(). - Added a bounded batch-drain loop to process additional ready
relocationCompleteevents (up to a fixed cap) in one choose-branch.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
fdbserver/include/fdbserver/DDRelocationQueue.h |
Declares the new processRelocationComplete() helper on DDQueue. |
fdbserver/DDRelocationQueue.actor.cpp |
Implements processRelocationComplete() and adds a bounded drain loop to reduce starvation/backlog. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Result of foundationdb-pr-73 on Linux RHEL 9
|
2 similar comments
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
2 similar comments
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
|
On the PR description, |
3fe923d to
2886089
Compare
|
Address the AI feedback at #12993 (comment) It is good. Commit has a note on how this is hard to test:
No debugger attached, no symbols, so can't say for sure. What we do see is rise in in-flight count correlates to rise in memory. Surviving fetchKeysComplete and associates are suspect. This PR attempts servicing of in-flight decrement and fetchKeysComplete freeing. Simulation is a bust here. Will go elsewhere to make a test. |
This isn't in production yet but shortly you should be able to have your buddy munge through our TraceEvent number stream and see if it can produce a graph of these move entities as against RSS or Arena related stats, and maybe we can line these graphs up to our satisfaction. Also maybe your buddy can figure out why the all-in overhead might really be 100K per move event. That seems hard to believe but maybe there is a bunch of misc actor state data structures laying around waiting to be freed for a whole pile of nearly dead actors who are waiting to be reaped, so to speak. (Sounds like an Oscar party.) |
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
2d7c0c4 to
3f6bd3d
Compare
|
Make the change smaller. Still working on a test. |
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
3f6bd3d to
cf2f20f
Compare
|
Added a counter that trips every time we batch. Add a unit test. Now trying to reproduce the scenario in n integration test. Will report back. |
The DDQueue choose loop processes one event per iteration. When dataTransferComplete and other events are frequent, relocationComplete processing is starved -- fetchKeysComplete entries (erased only in the relocationComplete handler) accumulate unboundedly. On p67 this reached 33,593 entries causing OOM. Fix: after processing the first relocationComplete via waitNext, batch drain all remaining ready completions (capped at 1000) before returning to the choose loop. Each drained completion gets the same processing as the original: processRelocationComplete + delay(0) -> rangesComplete for launchQueuedWork. The delay(0) -> rangesComplete -> keysToLaunchFrom path is preserved exactly as before. Changes: - Extract processRelocationComplete() for reuse in drain loop - Store FutureStream as state variable for isReady()/pop() access - Add RelocationCompleteBatchDrain trace event for observability - Add /dd/queue/relocationComplete/batchDrained SimpleCounter metric - Add unit test that sends 100 completions in a burst and verifies all are drained, fetchKeysComplete is emptied, and the counter increments
cf2f20f to
8451324
Compare
|
Rebase |
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
Result of foundationdb-pr-cluster-tests-73 on Linux RHEL 9
|
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-73 on Linux RHEL 9
|
Result of foundationdb-pr-clang-73 on Linux RHEL 9
|
Result of foundationdb-pr on Linux RHEL 9
|
Result of foundationdb-pr-macos-m1 on macOS Ventura 13.x
|

20260415-043932-stack_centos7_all_starvation-db5246251777f6a compressed=True data_size=51146319 duration=4673620 ended=99999 fail=1 fail_fast=10 max_runs=100000 pass=99998 priority=100 remaining=0:00:00 runtime=0:52:07 sanity=False started=100000 submitted=20260415-043932 timeout=5400 username=stack_centos7_all_starvationThe failure was RandomSeed="4014465418" SourceVersion="5bfd01720280600535c8bedf5c4bd2cbd4da453d" Time="1776228920" BuggifyEnabled="1" DeterminismCheck="0" FaultInjectionEnabled="1" TestFile="tests/fast/GetMappedRange.toml"