aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2016-10-06 09:46:40 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2016-10-06 09:46:40 +0300
commitb56fb691b0033f9b86e0552bd5adfd485f05eef6 (patch)
tree06818b313e3c114faebaaf60697982b8894c1e36 /src
parentbfe2e847811a4d0a46c8cdf16195c0e5929b6f83 (diff)
downloadpostgresql-b56fb691b0033f9b86e0552bd5adfd485f05eef6.tar.gz
postgresql-b56fb691b0033f9b86e0552bd5adfd485f05eef6.zip
Fix excessive memory consumption in the new sort pre-reading code.
LogicalTapeRewind() should not allocate large read buffer, if the tape is completely empty. The calling code relies on that, for its calculation of how much memory to allocate for the read buffers. That lead to massive overallocation of memory, if maxTapes was high, but only a few tapes were actually used. Reported by Tomas Vondra Discussion: <7303da46-daf7-9c68-3cc1-9f83235cf37e@2ndquadrant.com>
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/sort/logtape.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c
index caa6960b957..6cc06b24e0d 100644
--- a/src/backend/utils/sort/logtape.c
+++ b/src/backend/utils/sort/logtape.c
@@ -778,11 +778,16 @@ LogicalTapeRewind(LogicalTapeSet *lts, int tapenum, bool forWrite)
datablocknum = ltsRewindFrozenIndirectBlock(lts, lt->indirect);
}
- /* Allocate a read buffer */
+ /* Allocate a read buffer (unless the tape is empty) */
if (lt->buffer)
pfree(lt->buffer);
- lt->buffer = palloc(lt->read_buffer_size);
- lt->buffer_size = lt->read_buffer_size;
+ lt->buffer = NULL;
+ lt->buffer_size = 0;
+ if (datablocknum != -1L)
+ {
+ lt->buffer = palloc(lt->read_buffer_size);
+ lt->buffer_size = lt->read_buffer_size;
+ }
/* Read the first block, or reset if tape is empty */
lt->curBlockNumber = 0L;