Re: GiST VACUUM
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Andrey Borodin <x4mmm@yandex-team.ru>
Cc: Thomas Munro <thomas.munro@enterprisedb.com>, pgsql-hackers <pgsql-hackers@postgresql.org>, Костя Кузнецов <chapaev28@ya.ru>
Date: 2018-07-12T16:40:33Z
Lists: pgsql-hackers
On 12/07/18 19:06, Andrey Borodin wrote: >> 11 июля 2018 г., в 0:07, Heikki Linnakangas <hlinnaka@iki.fi> >> написал(а): >> >> This seems misplaced. This code deals with internal pages, and as >> far as I can see, this patch never marks internal pages as deleted, >> only leaf pages. However, we should have something like this in the >> leaf-page branch, to deal with the case that an insertion lands on >> a page that was concurrently deleted. Did you have any tests, where >> an insertion runs concurrently with vacuum, that would exercise >> this? > > That bug could manifest only in case of crash between removing > downlinks and marking pages deleted. Hmm. The downlink is removed first, so I don't think you can see that situation after a crash. After a crash, you might have some empty, orphaned, pages that have already been unlinked from the parent, but a search/insert should never encounter them. Actually, now that I think about it more, I'm not happy with leaving orphaned pages like that behind. Let's WAL-log the removal of the downlink, and marking the leaf pages as deleted, in one WAL record, to avoid that. But the situation in gistdoinsert(), where you encounter a deleted leaf page, could happen during normal operation, if vacuum runs concurrently with an insert. Insertion locks only one page at a time, as it descends the tree, so after it has released the lock on the parent, but before it has locked the child, vacuum might have deleted the page. In the latest patch, you're checking for that just before swapping the shared lock for an exclusive one, but I think that's wrong; you need to check for that after swapping the lock, because otherwise vacuum might delete the page while you're not holding the lock. > I do not know how to test this > reliably. Internal pages are locked before leafs and locks are > coupled. No cuncurrent backend can see downlinks to pages being > deleted, unless crash happens. Are you sure? At a quick glance, I don't think the locks are coupled. We do need some way of testing this.. - 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