jayzhan211 opened a new pull request, #25496:
URL: https://github.com/apache/datafusion/pull/25496

   ## Which issue does this PR close?
   
   - Closes #25269.
   
   ## Rationale for this change
   
   A hash join reserves every build-side batch as it arrives, then copies all 
of them
   into a single batch without reserving the copy, while the input batches stay 
alive
   until the build finishes. Near the memory limit the process therefore holds 
about
   twice the build side while the memory pool sees it once, so instead of a
   `ResourcesExhausted` error the process can be killed by the OS. It also means
   nothing that reacts to pool pressure can rely on what a hash join reports.
   
   Measured on a 1.25 GB build side (TPC-H SF1 `lineitem`, 16 columns, as the 
build
   side): the pool was charged ~1.25 GB while peak RSS was ~2.46 GB.
   
   ## What changes are included in this PR?
   
   - `concat_build_batches`: reserves the copy before `concat_batches`, drops 
the input
     batches, then trims the reservation to what the concatenated batch retains
     (`get_record_batch_memory_size`), growing instead if the estimate was low.
     `build_mem_used` follows every grow and shrink.
   - Nothing extra is reserved when there is nothing to copy: concatenating a 
single
     batch is zero-copy, and for `Utf8View`/`BinaryView` columns only the views 
are
     copied while the data buffers stay shared with the inputs.
   - `try_create_array_map` becomes `array_map_key_range`: it only decides 
whether the
     perfect hash join applies and reserves the `ArrayMap`. Both the hash map 
and the
     `ArrayMap` paths now hand the batches to the helper by value, so the 
inputs are
     gone before the visited bitmap and the null-aware scope maps are allocated.
   - Join key arrays that do not share the buffers of the build batch (any 
on-expression
     that is not a plain column) are kept for the whole join and are now 
reserved too.
     This uses a new public `RecordBatchMemoryCounter::count_array`.
   
   This does not reduce memory usage: the build still peaks at about twice the 
build
   side, it is now counted. A memory-limited query that only fit because the 
copy was
   not counted can now fail with `ResourcesExhausted`.
   
   ## What is the testing strategy for this PR?
   
   - `join_build_concat_is_reserved` (CollectLeft and Partitioned, hash map and
     `ArrayMap`): fails with `ResourcesExhausted` at map + 1.5x inputs, passes 
at
     map + 3x inputs. It fails on `main` in all four variants.
   - `join_build_key_arrays_are_reserved` (hash map and `ArrayMap`): with a 
single build
     batch and an `a1 + 1` join key, the join fails at inputs + map + half the 
key array
     and passes with room for it; a plain column key passes at the lower limit. 
It fails
     when the reservation is removed.
   - Unit tests of the helper: output equals `concat_batches` in both orders, 
the copy
     is reserved and the reservation then matches the retained batch, a single 
batch
     is not reserved twice, view data buffers are not reserved twice.
   - Existing `single_partition_join_overallocation` / 
`partitioned_join_overallocation`
     are unchanged.
   
   ## Are there any user-facing changes?
   
   One public addition: `RecordBatchMemoryCounter::count_array`. Hash joins 
running close
   to their memory limit may now report `ResourcesExhausted` where they 
previously exceeded the limit unnoticed.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to