Re: Tuplesort merge pre-reading - Mailing list pgsql-hackers

From Heikki Linnakangas
Subject Re: Tuplesort merge pre-reading
Date
Msg-id 9f7d8bb4-e954-37e4-1db4-ae2702fea4c7@iki.fi
Whole thread Raw
In response to Re: Tuplesort merge pre-reading  (Peter Geoghegan <pg@heroku.com>)
Responses Re: Tuplesort merge pre-reading  (Peter Geoghegan <pg@heroku.com>)
List pgsql-hackers
On 09/30/2016 04:08 PM, Peter Geoghegan wrote:
> On Thu, Sep 29, 2016 at 4:10 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
>> Bah, I fumbled the initSlabAllocator() function, attached is a fixed
>> version.
>
> This looks much better. It's definitely getting close. Thanks for
> being considerate of my more marginal concerns. More feedback:

Fixed most of the things you pointed out, thanks.

> * Minor issues with initSlabAllocator():
>
> You call the new function initSlabAllocator() as follows:
>
>> +   if (state->tuples)
>> +       initSlabAllocator(state, numInputTapes + 1);
>> +   else
>> +       initSlabAllocator(state, 0);
>
> Isn't the number of slots (the second argument to initSlabAllocator())
> actually just numInputTapes when we're "state->tuples"? And so,
> shouldn't the "+ 1" bit happen within initSlabAllocator() itself? It
> can just inspect "state->tuples" itself. In short, maybe push a bit
> more into initSlabAllocator(). Making the arguments match those passed
> to initTapeBuffers() a bit later would be nice, perhaps.

The comment above that explains the "+ 1". init_slab_allocator allocates 
the number of slots that was requested, and the caller is responsible 
for deciding how many slots are needed. Yeah, we could remove the 
argument and move the logic altogether into init_slab_allocator(), but I 
think it's clearer this way. Matter of taste, I guess.

> * This could be simpler, I think:
>
>> +   /* Release the read buffers on all the other tapes, by rewinding them. */
>> +   for (tapenum = 0; tapenum < state->maxTapes; tapenum++)
>> +   {
>> +       if (tapenum == state->result_tape)
>> +           continue;
>> +       LogicalTapeRewind(state->tapeset, tapenum, true);
>> +   }
>
> Can't you just use state->tapeRange, and remove the "continue"? I
> recommend referring to "now-exhausted input tapes" here, too.

Don't think so. result_tape == tapeRange only when the merge was done in 
a single pass (or you're otherwise lucky).

> * I'm not completely prepared to give up on using
> MemoryContextAllocHuge() within logtape.c just yet. Maybe you're right
> that it couldn't possibly matter that we impose a MaxAllocSize cap
> within logtape.c (per tape), but I have slight reservations that I
> need to address. Maybe a better way of putting it would be that I have
> some reservations about possible regressions at the very high end,
> with very large workMem. Any thoughts on that?

Meh, I can't imagine that using more than 1 GB for a read-ahead buffer 
could make any difference in practice. If you have a very large 
work_mem, you'll surely get away with a single merge pass, and 
fragmentation won't become an issue. And 1GB should be more than enough 
to trigger OS read-ahead.

Committed with some final kibitzing. Thanks for the review!

PS. This patch didn't fix bug #14344, the premature reuse of memory with 
tuplesort_gettupleslot. We'll still need to come up with 1. a 
backportable fix for that, and 2. perhaps a different fix for master.

- Heikki



pgsql-hackers by date:

Previous
From: Stas Kelvich
Date:
Subject: Re: WIP: About CMake v2
Next
From: Christoph Berg
Date:
Subject: Re: pgbench - allow backslash continuations in \set expressions