fix: free merge group spill aggregate states - #24575
Conversation
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
There was a problem hiding this comment.
Pull request overview
Fixes a memory leak in the MergeGroup operator where temporary aggregate states restored from partial-group payloads (ctr.spillAggList) were not consistently freed on the success path, leaving offheap mpool allocations live across batches.
Changes:
- Always free any existing
ctr.spillAggListbefore allocating a new temporary aggregate list for an incoming partial batch. - Free the temporary
spillAggListafter merging restored states into the mainctr.aggListand before callingneedSpill()(so spill decisions reflect post-merge memory). - Add a regression test asserting
spillAggListis cleared after each successful partial-batch merge.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pkg/sql/colexec/group/mergeGroup.go | Ensures spillAggList is freed on both success and error paths, preventing offheap state leaks across partial batches. |
| pkg/sql/colexec/group/group_test.go | Adds a regression test to verify spillAggList is cleared after each successful buildOneBatch merge. |
Merge Queue Status
This pull request spent 58 seconds in the queue, including 12 seconds running CI. Required conditions to merge
|
What type of PR is this?
Which issue(s) this PR fixes:
issue #24570
What this PR does / why we need it:
MergeGroup.buildOneBatch creates ctr.spillAggList for each incoming partial aggregate batch, then restores temporary aggregate state through aggExec.UnmarshalFromReader and merges it into ctr.aggList.
The previous code only released spillAggList on error. On the success path, the next input batch overwrote ctr.spillAggList, so previously restored aggregate state vectors were no longer reachable and their offheap mpool allocations remained live.
This PR:
releases any existing temporary spillAggList before creating a new one;
releases spillAggList after the partial aggregate state is merged and before needSpill() reads ctr.mp.CurrNB();
keeps deferred cleanup for error paths;
adds a regression test asserting that successful batch merge leaves ctr.spillAggList cleared.