Add spilling in SortMergeJoin #9359
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Is your feature request related to a problem or challenge?
In SortMergeJoin, it is possibly run of memory when it requires extra memory to hold polled buffer batches. We can consider adding spilling support there to make the operator resilient to the memory issue.
Describe the solution you'd like
Add spilling support in SortMergeJoin.
Describe alternatives you've considered
No response
Additional context
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
Omega359 commentedon Feb 27, 2024
Possibly related: #8398, #9170, #5108, #1599
comphead commentedon Apr 2, 2024
After reading some code and already opened issues on the same topic, probably its possible to summarize whats needed for POC at least:
comphead commentedon Apr 2, 2024
I'll try to start with creating a test query that fails on mem
comphead commentedon Apr 5, 2024
Related to #9846
comphead commentedon Apr 7, 2024
I think I managed to find the test query.
First observation is SMJ using external sorter, but the spill doesn't work, will dig into it.
This gives me a suggestion ExternalSorter used but spill is not used
Playing with sort params I managed to make SMJ merge phase complain on mem exhaustion
comphead commentedon Apr 7, 2024
My next steps
ExternalSorterMergedoesn't use spillwestonpace commentedon Apr 11, 2024
I can reproduce this pretty reliably in lance if it's any help. I run SortExec on a column of 100 million strings (each ~30 bytes long) and I have a 100MiB fair pool and it triggers in about 5 minutes. Let me know if there is anything I can do to assist you.
milenkovicm commentedon Apr 12, 2024
FWIW, I believe I was looking at this problem some time ago, if I remember correctly the issue was that one of the memory consumer, presumably
ExternalSorterMergewas returning all the memory it allocated just to ask for new allocation with similar size very soon after.MemoryConsumerwould return all the memory when dropped.My suspect is:
https://github.com/apache/arrow-datafusion/blob/a5cf0b8902ae55b81ac86b875c7e94cf1bdc205d/datafusion/physical-plan/src/sorts/sort.rs#L263
or
https://github.com/apache/arrow-datafusion/blob/a5cf0b8902ae55b81ac86b875c7e94cf1bdc205d/datafusion/physical-plan/src/sorts/sort.rs#L359
or somewhere around it.
line
may back my clain
I cant find more information looks like that branch is MIA
comphead commentedon Apr 12, 2024
Thanks, I'm planning to check next week if spilling works or not for ExternalSorter used for SMJ and see how it is possible to make spilling work as well for the merge phase, the memory pool is injected and SMJ get new allocations through
try_growso lets see what we can docomphead commentedon Jun 6, 2024
Finally starting on it. The test doesn't work anymore
viirya commentedon Jun 6, 2024
Yes, I tried the above test few days ago but it doesn't work now.
comphead commentedon Jun 6, 2024
I made it work that way (notice
-m 1m)Weird the same thing as a test doesn't respect memory pool
comphead commentedon Jun 7, 2024
the first use case is to try spilling for buffered data, as the buffered data comes in full size and eats the memory.
This is proved by query below
UPD: Buffered data comes in by partitions, every partition gets processed sequentially. The flow is approx:
Looks like the spilling needed in 1 place only