Re: GiST VACUUM

Heikki Linnakangas <hlinnaka@iki.fi>

From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Andrey Borodin <x4mmm@yandex-team.ru>
Cc: Michael Paquier <michael@paquier.xyz>, Thomas Munro <thomas.munro@enterprisedb.com>, Robert Haas <robertmhaas@gmail.com>, pgsql-hackers <pgsql-hackers@postgresql.org>, Костя Кузнецов <chapaev28@ya.ru>
Date: 2019-04-04T15:15:21Z
Lists: pgsql-hackers

Attachments

On 25/03/2019 15:20, Heikki Linnakangas wrote:
> On 24/03/2019 18:50, Andrey Borodin wrote:
>> I was working on new version of gist check in amcheck and understand one more thing:
>>
>> /* Can this page be recycled yet? */
>> bool
>> gistPageRecyclable(Page page)
>> {
>>       return PageIsNew(page) ||
>>           (GistPageIsDeleted(page) &&
>>            TransactionIdPrecedes(GistPageGetDeleteXid(page), RecentGlobalXmin));
>> }
>>
>> Here RecentGlobalXmin can wraparound and page will become unrecyclable for half of xid cycle. Can we prevent it by resetting PageDeleteXid to InvalidTransactionId before doing RecordFreeIndexPage()?
>> (Seems like same applies to GIN...)
> 
> True, and B-tree has the same issue. I thought I saw a comment somewhere
> in the B-tree code about that earlier, but now I can't find it. I
> must've imagined it.
> 
> We could reset it, but that would require dirtying the page. That would
> be just extra I/O overhead, if the page gets reused before XID
> wraparound. We could avoid that if we stored the full XID+epoch, not
> just XID. I think we should do that in GiST, at least, where this is
> new. In the B-tree, it would require some extra code to deal with
> backwards-compatibility, but maybe it would be worth it even there.

I suggest that we do the attached. It fixes this for GiST. The patch 
changes expands the "deletion XID" to 64-bits, and changes where it's 
stored. Instead of storing it pd_prune_xid, it's stored in the page 
contents. Luckily, a deleted page has no real content.

I think we should fix this in a similar manner in B-tree, too, but that 
can be done separately. For B-tree, we need to worry about 
backwards-compatibility, but that seems simple enough; we just need to 
continue to understand old deleted pages, where the deletion XID is 
stored in the page opaque field.

- Heikki

Commits

  1. Use full 64-bit XID for checking if a deleted GiST page is old enough.

  2. Refactor checks for deleted GiST pages.

  3. Delete empty pages during GiST VACUUM.

  4. Scan GiST indexes in physical order during VACUUM.

  5. Prevent GIN deleted pages from being reclaimed too early