Re: Should pg 11 use a lot more memory building an spgist index?

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>
Cc: Alexander Korotkov <akorotkov(at)postgresql(dot)org>, Amit Langote <Langote_Amit_f8(at)lab(dot)ntt(dot)co(dot)jp>, Bruno Wolff III <bruno(at)wolff(dot)to>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Should pg 11 use a lot more memory building an spgist index?
Date: 2018-10-29 19:48:37
Message-ID: 20752.1540842517@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers

I wrote:
> Alvaro Herrera <alvherre(at)2ndquadrant(dot)com> writes:
>> How about modifying SysScanDescData to have a memory context member,
>> which is created by systable_beginscan and destroyed by endscan?

> I think it would still have problems, in that it would affect in which
> context index_getnext delivers its output. We could reasonably make
> these sorts of changes in places where the entire index_beginscan/
> index_getnext/index_endscan call structure is in one place, but that
> doesn't apply for the systable functions.

Actually, after looking more closely, index_getnext doesn't return a
palloc'd object anyway, or at least not one that the caller is responsible
for managing. So maybe that could work.

I was confused about why the memory leak in Bruno's example is so much
larger in HEAD than v11; spgbeginscan does allocate more stuff than
before, but only if numberOfOrderBys > 0, which surely doesn't apply for
the exclusion-check code path. Eventually I realized that the difference
is because commit 2a6368343 made SpGistScanOpaqueData a good deal larger
than it had been (10080 vs 6264 bytes, on my x86_64 box), so it was just
the failure to pfree that struct that accounted for the bigger leak.

There's another issue with 2a6368343, though: it added a couple of
fmgr_info_copy calls to spgbeginscan. I don't understand why it'd be a
good idea to do that rather than using the FmgrInfos in the index's
relcache entry directly. Making a copy every time risks a memory leak,
because spgendscan has no way to free any fn_extra data that gets
allocated by the called function; and by the same token it's inefficient,
because the function has no way to cache fn_extra data across queries.

If we consider only the leak aspect, this coding presents a reason why
we should try to change things as Alvaro suggests. However, because of
the poor-caching aspect, I think this code is pretty broken anyway,
and once we fix it the issue is much less clear-cut.

(Looking around, it seems like we're very schizophrenic about whether
to copy index relcache support function FmgrInfos or just use them
directly. But nbtree and hash seem to always do the latter, so I think
it's probably reasonable to standardize on that.)

Anyway, the attached proposed patch for HEAD makes Bruno's problem go
away, and it also fixes an unrelated leak introduced by 2a6368343
because it reallocates so->orderByTypes each time through spgrescan.
I think we should apply this, and suitable subsets in the back branches,
to fix the immediate problem. Then we can work at leisure on a more
invasive HEAD-only patch, if anyone is excited about that.

regards, tom lane

Attachment Content-Type Size
fix-spgist-memory-leaks-1.patch text/x-diff 3.3 KB

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Rich Shepard 2018-10-29 20:21:37 Re: Redirecting select() output generates error [FIXED]
Previous Message Rob Sargent 2018-10-29 19:42:06 Re: Redirecting select() output generates error

Browse pgsql-hackers by date

  From Date Subject
Next Message Axel Rau 2018-10-29 22:05:11 Getting fancy errors when accessing information_schema on 10.5
Previous Message Andres Freund 2018-10-29 19:13:04 Re: replication_slots usability issue