fix(rfc): honour the row budget for single-column scans - #138
Merged
Conversation
`MaxBatchSizeForColumnCount` short-circuited to MAX_BATCH_SIZE whenever a scan
projected one column, so the budget `ResolveEffectiveMaxBatchSize` had just divided
across the partition workers was thrown away. Every worker issued ROWCOUNT=32768
regardless of erpl_rfc_fetch_size or partitions.
The exemption was deliberate and its comment said so -- a narrow scan is already
under any sane budget. That holds for the undivided budget and stops holding the
moment it is divided by the worker count, which is exactly the case partitioning
creates. Narrow scans are what partitioning is for, so this was the one shape where
the knobs mattered most and did nothing.
Found by profiling the two RFC backends: heaptrack showed 32768-row batches on every
worker at partitions=8, on both backends, whatever the settings said.
Measured on 300,000 rows of REPOSRC, one column, partitions=8, release build:
nwrfc peak RSS 405 MB -> 307 MB (-24%), wall 2.17s -> 2.07s
No throughput cost at this shape; the smaller batch is offset by the workers no
longer contending for one oversized SDK buffer each.
Also trims the allocator arena when a partitioned worker retires. The serial path
already does this when the scan finishes (issue #69); the partitioned path returns
through a different branch that did not, so each worker thread's glibc arena kept its
high-water mark -- which is the number getrusage reports.
Note this does NOT move the erpl-proto backend (691 MB, unchanged), whose peak scales
with rows read rather than rows in flight. That is a separate defect, reported with
its heaptrack attribution as DataZooDE/erpl-proto#61.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sap_read_table'sfetch_sizeandpartitionsdid nothing to the batch size of asingle-column scan.
MaxBatchSizeForColumnCountshort-circuited toMAX_BATCH_SIZEwhenever a scan projectedone column, discarding the budget
ResolveEffectiveMaxBatchSizehad just divided acrossthe partition workers. Every worker issued
ROWCOUNT=32768howevererpl_rfc_fetch_sizeand
partitionswere set.The exemption was deliberate, and its comment said why: a narrow scan is already under any
sane budget. That is true of the undivided budget and stops being true the moment it is
divided by the worker count — which is the case partitioning creates. Narrow scans are what
partitioning is for, so this was the one shape where the knobs mattered most and did
nothing.
How it was found
Profiling the two RFC backends against each other. heaptrack showed 32768-row batches on
every worker at
partitions=8, on both backends, regardless of the settings — whichis not what the tuning API advertises.
The single-column bypass was first spotted by a multi-agent review of the two codebases;
the profiler then confirmed it and refuted that review's wider model.
Measured
300,000 rows of
REPOSRC, one column,partitions=8, release build, a4h:No throughput cost at this shape. Checksums identical before and after, on both backends.
Also
A partitioned scan never returned its allocator arenas. The serial path calls
malloc_trim(0)when the scan finishes (#69), but a partition worker retires through adifferent branch that did not, so each worker thread's glibc arena kept its high-water
mark — which is the number
getrusagereports.What this does NOT fix
The erpl-proto backend is unchanged at 691 MB. Its peak scales with rows read rather
than rows in flight — a 16× smaller batch does not move it, while total rows do
(293 / 389 / 694 MB for 75k / 150k / 300k rows, ~2.3 KB retained per row). That is a
separate defect, reported with its heaptrack attribution as DataZooDE/erpl-proto#61.
Tests
test_read_table_batching.cpp: a new case asserting the budget binds for one column —red before this change (
32768 == 2048failed), green after. The existing wide-scanassertions are unchanged and still pass, because a large budget still yields the full
batch; only a small (divided) budget now binds.
Behaviour note
A serial single-column scan now uses a 16384-row batch rather than 32768, because the
default budget is 16384 concurrent rows and it is now honoured rather than bypassed. That
is the documented contract; raise
erpl_rfc_fetch_sizeto restore the old batch.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.