Re: GiST VACUUM
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Andrey Borodin <x4mmm@yandex-team.ru>, Robert Haas <robertmhaas@gmail.com>
Cc: Thomas Munro <thomas.munro@enterprisedb.com>, pgsql-hackers <pgsql-hackers@postgresql.org>, Костя Кузнецов <chapaev28@ya.ru>
Date: 2018-07-18T12:02:05Z
Lists: pgsql-hackers
On 17/07/18 21:41, Andrey Borodin wrote:
> I was checking WAL replay of new scheme to log page deletes and found
> a bug there (incorrect value of deleted downlink in WAL record).
> Here's fixed patch v10.
>
> Also I've added support to WAL identification for new record, done
> some improvements to comments and naming in data structures.
Thanks!
> + /*
> + * If this page was splitted after start of the VACUUM we have to
> + * revisit rightlink, if it points to block we already scanned.
> + * This is recursive revisit, should not be deep, but we check
> + * the possibility of stack overflow anyway.
> + */
> + if ((GistFollowRight(page) || startNSN < GistPageGetNSN(page)) &&
> + (opaque->rightlink != InvalidBlockNumber) && (opaque->rightlink < blkno))
> + {
> + gistbulkdeletephysicalcanpage(info, stats, callback, callback_state, opaque->rightlink, startNSN, graph);
> + }
In the corresponding B-tree code, we use don't do actual recursion, but
a hand-optimized "tail recursion", to avoid stack overflow if there are
a lot of splits. I think we need to do something like tha there, too. I
don't think it's safe to assume that we have enough stack space for the
recursion. You have a check_stack_depth() in the function, so you'll get
ERROR, but it sucks if VACUUM errors out because of that.
It's not cool to use up to 'maintenance_work_mem' of memory for holding
the in-memory graph. VACUUM already uses up to that much memory to hold
the list of dead TIDs, so we would use up to 2x maintenance_work_mem in
total.
The only reason we still need the logical scan is to support page
deletion, when there is not enough memory available. Can we get rid of
that altogether? I think I'd prefer some other scheme to deal with that
situation. For example, we could make note, in memory, of the empty
pages during the physical scan, and perform a second physical scan of
the index to find their downlinks. Two full-index scans is not nice, but
it's actually not that bad if it's done in physical order. And you could
have some heuristics, e.g. only do it if more than 10% of the pages were
deletable.
Sorry to ask you to rewrite this again, but I think it would be better
to split this into two patches as follows:
1st patch: Scan the index in physical rather than logical order. No
attempt at deleting empty pages yet.
2nd patch: Add support for deleting empty pages.
I would be more comfortable reviewing and committing that first patch,
which just switches to doing physical-order scan, first.
- Heikki
Commits
-
Use full 64-bit XID for checking if a deleted GiST page is old enough.
- fb5344c969af 12.0 landed
- 6655a7299d83 13.0 landed
-
Refactor checks for deleted GiST pages.
- e2e992c93145 12.0 landed
- 9eb5607e6993 13.0 landed
-
Delete empty pages during GiST VACUUM.
- 7df159a620b7 12.0 landed
-
Scan GiST indexes in physical order during VACUUM.
- fe280694d0d4 12.0 landed
-
Prevent GIN deleted pages from being reclaimed too early
- 52ac6cd2d0cd 12.0 cited