mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
Fix accounting of memory needed for merge heap.
We allegedly allocated all remaining memory for the read buffers of the sort tapes, but we allocated the merge heap only after that. That means that the allocation of the merge heap was guaranteed to go over the memory limit. Fix by allocating the merge heap first. This makes little difference in practice, because the merge heap is tiny, but let's tidy. While we're at it, add a safeguard for the case that we are already over the limit when allocating the read buffers. That shouldn't happen, but better safe than sorry. The memory accounting error was reported off-list by Peter Geoghegan.
This commit is contained in:
parent
cd5d3af44e
commit
f7d54f4f7d
@ -2637,8 +2637,16 @@ mergeruns(Tuplesortstate *state)
|
||||
}
|
||||
|
||||
/*
|
||||
* Use all the spare memory we have available for read buffers among the
|
||||
* input tapes.
|
||||
* Allocate a new 'memtuples' array, for the heap. It will hold one tuple
|
||||
* from each input tape.
|
||||
*/
|
||||
state->memtupsize = numInputTapes;
|
||||
state->memtuples = (SortTuple *) palloc(numInputTapes * sizeof(SortTuple));
|
||||
USEMEM(state, GetMemoryChunkSpace(state->memtuples));
|
||||
|
||||
/*
|
||||
* Use all the remaining memory we have available for read buffers among
|
||||
* the input tapes.
|
||||
*
|
||||
* We do this only after checking for the case that we produced only one
|
||||
* initial run, because there is no need to use a large read buffer when
|
||||
@ -2661,17 +2669,9 @@ mergeruns(Tuplesortstate *state)
|
||||
(state->availMem) / 1024, numInputTapes);
|
||||
#endif
|
||||
|
||||
state->read_buffer_size = state->availMem / numInputTapes;
|
||||
state->read_buffer_size = Min(state->availMem / numInputTapes, 0);
|
||||
USEMEM(state, state->availMem);
|
||||
|
||||
/*
|
||||
* Allocate a new 'memtuples' array, for the heap. It will hold one tuple
|
||||
* from each input tape.
|
||||
*/
|
||||
state->memtupsize = numInputTapes;
|
||||
state->memtuples = (SortTuple *) palloc(numInputTapes * sizeof(SortTuple));
|
||||
USEMEM(state, GetMemoryChunkSpace(state->memtuples));
|
||||
|
||||
/* End of step D2: rewind all output tapes to prepare for merging */
|
||||
for (tapenum = 0; tapenum < state->tapeRange; tapenum++)
|
||||
LogicalTapeRewindForRead(state->tapeset, tapenum, state->read_buffer_size);
|
||||
|
Loading…
Reference in New Issue
Block a user