Re: BUG #17255: Server crashes in index_delete_sort_cmp() due to race condition with vacuum
Andres Freund <andres@anarazel.de>
From: Andres Freund <andres@anarazel.de>
To: Peter Geoghegan <pg@bowt.ie>
Cc: Dmitry Dolgov <9erthalion6@gmail.com>, Alexander Lakhin <exclusion@gmail.com>, Matthias van de Meent <boekewurm+postgres@gmail.com>, PostgreSQL mailing lists <pgsql-bugs@lists.postgresql.org>
Date: 2022-03-10T00:25:05Z
Lists: pgsql-bugs
Hi, On 2022-03-03 16:22:11 -0800, Peter Geoghegan wrote: > Attached is (roughly speaking) a rebased version of this patch (i.e. > your v4-0004- patch from the patch series). Like your patch, this > patch documents our expectations for vistest and OldestXmin. Unlike > your patch, it makes all vacrel initialization take place before > lazy_scan_heap is called, from inside heap_vacuum_rel. I think it'd be nicer if we did the horizon determination after allocating space for dead tuples... But it's still better than today, so... > An important detail here is how OldestXmin (and vistest) are related > to rel_pages -- I also added something about that. It definitely > wouldn't be okay to (say) move the call to RelationGetNumberOfBlocks > to any place before the call to vacuum_set_xid_limits. And so it very > much seems in scope here. You're right, it needs to be that way round. > I'm a bit confused about at least one detail here: you've said here > that "GlobalVisTestFor() doesn't itself do any horizon determination", > which seems to contradict comments from the v4-0004- patch that was > attached to the same email. Which comment in the patch is the quoted statement contradicting? The on-point comment seems to be + * [...] vacrel->vistest is always at least as aggressive as the + * limits vacuum_set_xid_limits() computes because ComputeXidHorizons() + * (via vacuum_set_xid_limits() ->GetOldestNonRemovableTransactionId()) + * ensures the approximate horizons are always at least as aggressive as + * the precise horizons. > + * Also, we delay establishing vistest + * as a minor optimization. A > later cutoff can enable more eager pruning. + */ I don't think the minor optimization does anything (which I had stated wrongly at some point in this thread). > /* > * Call lazy_scan_heap to perform all required heap pruning, index > - * vacuuming, and heap vacuuming (plus related processing) > + * vacuuming, and heap vacuuming (plus related processing). > + * > + * Note: Resource management for parallel VACUUM is quite subtle, and so > + * lazy_scan_heap must allocate (and deallocate) vacrel->dead_items space > + * for itself. Every other vacrel field is initialized by now, though. > */ > lazy_scan_heap(vacrel, params->nworkers); What are you referring to with "quite subtle"? Greetings, Andres Freund
Commits
-
vacuumlazy.c: Standardize rel_pages terminology.
- e370f100f05d 15.0 landed
-
vacuumlazy.c: document vistest and OldestXmin.
- 73f6ec3d3c8d 15.0 landed
-
heap pruning: Only call BufferGetBlockNumber() once.
- c702d656a283 15.0 landed
-
Fix possible HOT corruption when RECENTLY_DEAD changes to DEAD while pruning.
- dad1539aec28 14.2 landed
- 18b87b201f73 15.0 landed
-
Assert redirect pointers are sensible after heap_page_prune().
- bb42bfb5ccb5 15.0 landed
-
Remove tupgone special case from vacuumlazy.c.
- 8523492d4e34 14.0 cited
-
Recycle nbtree pages deleted during same VACUUM.
- 9dd963ae2534 14.0 cited
-
snapshot scalability: Don't compute global horizons while building snapshots.
- dc7420c2c927 14.0 cited
-
Refactor heap_page_prune so that instead of changing item states on-the-fly,
- 6f10eb21118f 8.4.0 cited