• Peter Geoghegan's avatar
    Fix index deletion latestRemovedXid bug. · 42288174
    Peter Geoghegan authored
    The logic for determining the latest removed XID for the purposes of
    generating recovery conflicts in REDO routines was subtly broken.  It
    failed to follow links from HOT chains, and so failed to consider all
    relevant heap tuple headers in some cases.
    
    To fix, expand the loop that deals with LP_REDIRECT line pointers to
    also deal with HOT chains.  The new version of the loop is loosely based
    on a similar loop from heap_prune_chain().
    
    The impact of this bug is probably quite limited, since the horizon code
    necessarily deals with heap tuples that are pointed to by LP_DEAD-set
    index tuples.  The process of setting LP_DEAD index tuples (e.g. within
    the kill_prior_tuple mechanism) is highly correlated with opportunistic
    pruning of pointed-to heap tuples.  Plus the question of generating a
    recovery conflict usually comes up some time after index tuple LP_DEAD
    bits were initially set, unlike heap pruning, where a latestRemovedXid
    is generated at the point of the pruning operation (heap pruning has no
    deferred "would-be page split" style processing that produces conflicts
    lazily).
    
    Only backpatch to Postgres 12, the first version where this logic runs
    during original execution (following commit 558a9165).  The index
    latestRemovedXid mechanism has had the same bug since it first appeared
    over 10 years ago (in commit a760893d), but backpatching to all
    supported versions now seems like a bad idea on balance.  Running the
    new improved code during recovery seems risky, especially given the lack
    of complaints from the field.
    
    Author: Peter Geoghegan <pg@bowt.ie>
    Discussion: https://postgr.es/m/CAH2-Wz=Eib393+HHcERK_9MtgNS7Ew1HY=RDC_g6GL46zM5C6Q@mail.gmail.com
    Backpatch: 12-
    42288174
heapam.c 272 KB