Skip to content

Account for transformer-retained batches in symmetric hash join - #24364

Draft
kosiew wants to merge 9 commits into
apache:mainfrom
kosiew:memcalc-03-23393
Draft

Account for transformer-retained batches in symmetric hash join#24364
kosiew wants to merge 9 commits into
apache:mainfrom
kosiew:memcalc-03-23393

Conversation

@kosiew

@kosiew kosiew commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

The symmetric hash join can retain an output RecordBatch in its batch transformer without including that batch in the stream's memory reservation.

As a result, the stream can under-account memory while either NoopBatchTransformer or BatchSplitter holds a batch. The retained batch may also share Arrow buffers or nested arrays with other stream state, so simply adding individual batch memory sizes can double-count shared allocations.

This PR accounts for transformer-retained batches at the symmetric hash join stream reservation boundary while deduplicating shared Arrow allocations. Corrected accounting can increase reservation pressure under bounded memory pools, without changing join results.

What changes are included in this PR?

  • Extend RecordBatchMemoryCounter with sequence-aware accounting for both Arrow buffers and array-object overhead, including shared nested arrays.
  • Add BatchTransformer::count_memory so NoopBatchTransformer and BatchSplitter report memory retained by their current batch through the shared counter.
  • Include the left and right input buffers and transformer-retained batch in a single RecordBatchMemoryCounter when calculating SymmetricHashJoinStream::size(), avoiding duplicate accounting of shared allocations.
  • Add SymmetricHashJoinStream::update_reservation() and update the reservation when a transformer acquires or releases a batch.
  • Leave the unrelated OneSideHashJoiner accounting formulas unchanged.

Are these changes tested?

Yes. The patch adds the following regression tests:

  • test_record_batch_memory_counter_array_overhead_shared_across_batches
  • test_record_batch_memory_counter_deduplicates_shared_nested_array_overhead
  • test_record_batch_memory_counter_deduplicates_recursive_shared_children
  • batch_transformers_count_retained_batch_memory
  • stream_accounts_for_transformer_batches_once
  • stream_deduplicates_nested_transformer_batches
  • symmetric_hash_join_reserves_transformer_batch

These cover transformer-retained batches for both NoopBatchTransformer and BatchSplitter, shared buffers and nested arrays, reservation/metric updates when transformer ownership changes, and bounded-memory behavior when the previously unaccounted retained batch pushes the join over the configured memory limit.

Are there any user-facing changes?

There are no changes to join result semantics or public APIs.

Memory accounting for symmetric hash joins is more complete. Workloads running near a configured memory limit may therefore encounter memory-pressure behavior earlier because transformer-retained batches are now included in the stream reservation.

LLM-generated code disclosure

This PR includes LLM-generated code and comments. All LLM-generated content has been manually reviewed.

kosiew added 8 commits August 14, 2026 19:04
…d batches, deduplicate shared buffers, and update reservation lifecycle**

- RecordBatchMemoryCounter now tracks transformer retained batches.
- Symmetric stream deduplicates input/transformer shared buffers.
- Reservation updates occur on retain and release operations.
- Added tests for noop, splitter, shared buffers, and reservation lifecycle.
* Preserve RecordBatch array-object/non-buffer overhead while deduplicating Arrow buffer capacities in memory reservations.
* Ensure transformer-held batches are fully accounted for in bounded-memory enforcement.
* Add wide/nested retained-batch regression coverage for non-buffer allocation overhead.
* Add execution-level bounded-memory tests using SymmetricHashJoinExec with a tight GreedyMemoryPool.
* Verify NoopBatchTransformer and BatchSplitter retained batches correctly affect reservations and memory-limit behavior.
…age for children (Struct, List, Map, Union, Dict, RunEnd), plus regression test for shared nested StructArray child
…p contract; add regression-boundary rationale comment for 2_400 test limit
…n, Dictionary, RunEnd and improve shared allocation delta checks
…ArrayRef clones

- Introduces a private assertion helper for testing.
- Removes unnecessary ArrayRef clones after construction, improving efficiency.
@github-actions github-actions Bot added common Related to common crate physical-plan Changes to the physical-plan crate labels Aug 14, 2026
…n and memory usage

- Polls transformer output to exhaustion.
- Asserts reservation + stream_memory_usage grow on retain, return baseline on release.
- Covers Noop + BatchSplitter.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.25581% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.19%. Comparing base (1f0615a) to head (792fa41).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
datafusion/common/src/utils/memory.rs 90.70% 25 Missing ⚠️
...ion/physical-plan/src/joins/symmetric_hash_join.rs 96.92% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #24364      +/-   ##
==========================================
+ Coverage   81.17%   81.19%   +0.01%     
==========================================
  Files        1109     1109              
  Lines      388117   388591     +474     
  Branches   388117   388591     +474     
==========================================
+ Hits       315071   315528     +457     
- Misses      54504    54515      +11     
- Partials    18542    18548       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common Related to common crate physical-plan Changes to the physical-plan crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants