Skip to content

Commit f214960

Browse files
Update obsolete heap pruning comments.
Add new comments that spell out what VACUUM expects from heap pruning: pruning must never leave behind DEAD tuples that still have tuple storage. This has at least been the case since commit 8523492, which established the principle that vacuumlazy.c doesn't have to deal with DEAD tuples that still have tuple storage directly, except perhaps by simply retrying pruning (to handle a rare corner case involving concurrent transaction abort). In passing, update some references to old symbol names that were missed by the snapshot scalability work (specifically commit dc7420c).
1 parent 4a92a1c commit f214960

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/backend/access/heap/pruneheap.c

+14-6
Original file line numberDiff line numberDiff line change
@@ -488,17 +488,25 @@ heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup, Buffer buffer)
488488
* the HOT chain is pruned by removing all DEAD tuples at the start of the HOT
489489
* chain. We also prune any RECENTLY_DEAD tuples preceding a DEAD tuple.
490490
* This is OK because a RECENTLY_DEAD tuple preceding a DEAD tuple is really
491-
* DEAD, the OldestXmin test is just too coarse to detect it.
491+
* DEAD, the heap_prune_satisfies_vacuum test is just too coarse to detect it.
492+
*
493+
* In general, pruning must never leave behind a DEAD tuple that still has
494+
* tuple storage. VACUUM isn't prepared to deal with that case. That's why
495+
* VACUUM prunes the same heap page a second time (without dropping its lock
496+
* in the interim) when it sees a newly DEAD tuple that we initially saw as
497+
* in-progress. Retrying pruning like this can only happen when an inserting
498+
* transaction concurrently aborts.
492499
*
493500
* The root line pointer is redirected to the tuple immediately after the
494501
* latest DEAD tuple. If all tuples in the chain are DEAD, the root line
495502
* pointer is marked LP_DEAD. (This includes the case of a DEAD simple
496503
* tuple, which we treat as a chain of length 1.)
497504
*
498-
* OldestXmin is the cutoff XID used to identify dead tuples.
505+
* prstate->vistest is used to distinguish whether tuples are DEAD or
506+
* RECENTLY_DEAD.
499507
*
500508
* We don't actually change the page here, except perhaps for hint-bit updates
501-
* caused by HeapTupleSatisfiesVacuum. We just add entries to the arrays in
509+
* caused by heap_prune_satisfies_vacuum. We just add entries to the arrays in
502510
* prstate showing the changes to be made. Items to be redirected are added
503511
* to the redirected[] array (two entries per redirection); items to be set to
504512
* LP_DEAD state are added to nowdead[]; and items to be set to LP_UNUSED
@@ -694,9 +702,9 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
694702
/*
695703
* Remember the last DEAD tuple seen. We will advance past
696704
* RECENTLY_DEAD tuples just in case there's a DEAD one after them;
697-
* but we can't advance past anything else. (XXX is it really worth
698-
* continuing to scan beyond RECENTLY_DEAD? The case where we will
699-
* find another DEAD tuple is a fairly unusual corner case.)
705+
* but we can't advance past anything else. We have to make sure that
706+
* we don't miss any DEAD tuples, since DEAD tuples that still have
707+
* tuple storage after pruning will confuse VACUUM.
700708
*/
701709
if (tupdead)
702710
{

0 commit comments

Comments
 (0)