From: | Peter Geoghegan <pg(at)heroku(dot)com> |
---|---|
To: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
Cc: | Tomas Vondra <tomas(dot)vondra(at)2ndquadrant(dot)com>, Pg Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: memory leak in e94568ecc10 (pre-reading in external sort) |
Date: | 2016-10-10 21:56:09 |
Message-ID: | CAM3SWZTAT8YxknqZ+H61hqFBU7DG8ifZwQNzebYf9JsLmrNmtA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Mon, Oct 10, 2016 at 5:21 AM, Heikki Linnakangas <hlinnaka(at)iki(dot)fi> wrote:
> Admittedly that's confusing. Thinking about this some more, I came up with
> the attached. I removed the separate LogicalTapeAssignReadBufferSize() call
> altogether - the read buffer size is now passed as argument to the
> LogicalTapeRewindForRead() call.
>
> I split LogicalTapeRewind() into two: LogicalTapeRewindForRead() and
> LogicalTapeRewindForWrite(). A boolean argument like 'forWrite' is mentally
> challenging, because when reading a call site, you have to remember which
> way round the boolean is. And now you also pass the extra buffer_size
> argument when rewinding for reading, but not when writing.
I like the general idea here.
> I gave up on the logic to calculate the quotient and reminder of the
> available memory, and assigning one extra buffer to some of the tapes. I'm
> now just rounding it down to the nearest BLCKSZ boundary. That simplifies
> the code further, although we're now not using all the memory we could. I'm
> pretty sure that's OK, although I haven't done any performance testing of
> this.
The only thing I notice is that this new struct field could use a comment:
> --- a/src/backend/utils/sort/tuplesort.c
> +++ b/src/backend/utils/sort/tuplesort.c
> @@ -366,6 +366,8 @@ struct Tuplesortstate
> char *slabMemoryEnd; /* end of slab memory arena */
> SlabSlot *slabFreeHead; /* head of free list */
>
> + size_t read_buffer_size;
> +
Also, something about trace_sort here:
> +#ifdef TRACE_SORT
> + if (trace_sort)
> + elog(LOG, "using " INT64_FORMAT " KB of memory for read buffers among %d input tapes",
> + (state->availMem) / 1024, numInputTapes);
> +#endif
> +
> + state->read_buffer_size = state->availMem / numInputTapes;
> + USEMEM(state, state->availMem);
Maybe you should just make the trace_sort output talk about blocks at
this point?
--
Peter Geoghegan
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2016-10-10 22:03:14 | De-support SCO OpenServer/SCO UnixWare? |
Previous Message | Andres Freund | 2016-10-10 21:00:43 | Re: Supporting huge pages on Windows |