• Peter Geoghegan's avatar
    Remove tupgone special case from vacuumlazy.c. · 8523492d
    Peter Geoghegan authored
    Retry the call to heap_prune_page() in rare cases where there is
    disagreement between the heap_prune_page() call and the call to
    HeapTupleSatisfiesVacuum() that immediately follows.  Disagreement is
    possible when a concurrently-aborted transaction makes a tuple DEAD
    during the tiny window between each step.  This was the only case where
    a tuple considered DEAD by VACUUM still had storage following pruning.
    VACUUM's definition of dead tuples is now uniformly simple and
    unambiguous: dead tuples from each page are always LP_DEAD line pointers
    that were encountered just after we performed pruning (and just before
    we considered freezing remaining items with tuple storage).
    
    Eliminating the tupgone=true special case enables INDEX_CLEANUP=off
    style skipping of index vacuuming that takes place based on flexible,
    dynamic criteria.  The INDEX_CLEANUP=off case had to know about skipping
    indexes up-front before now, due to a subtle interaction with the
    special case (see commit dd695979) -- this was a special case unto
    itself.  Now there are no special cases.  And so now it won't matter
    when or how we decide to skip index vacuuming: it won't affect how
    pruning behaves, and it won't be affected by any of the implementation
    details of pruning or freezing.
    
    Also remove XLOG_HEAP2_CLEANUP_INFO records.  These are no longer
    necessary because we now rely entirely on heap pruning taking care of
    recovery conflicts.  There is no longer any need to generate recovery
    conflicts for DEAD tuples that pruning just missed.  This also means
    that heap vacuuming now uses exactly the same strategy for recovery
    conflicts as index vacuuming always has: REDO routines never need to
    process a latestRemovedXid from the WAL record, since earlier REDO of
    the WAL record from pruning is sufficient in all cases.  The generic
    XLOG_HEAP2_CLEAN record type is now split into two new record types to
    reflect this new division (these are called XLOG_HEAP2_PRUNE and
    XLOG_HEAP2_VACUUM).
    
    Also stop acquiring a super-exclusive lock for heap pages when they're
    vacuumed during VACUUM's second heap pass.  A regular exclusive lock is
    enough.  This is correct because heap page vacuuming is now strictly a
    matter of setting the LP_DEAD line pointers to LP_UNUSED.  No other
    backend can have a pointer to a tuple located in a pinned buffer that
    can be invalidated by a concurrent heap page vacuum operation.
    
    Heap vacuuming can now be thought of as conceptually similar to index
    vacuuming and conceptually dissimilar to heap pruning.  Heap pruning now
    has sole responsibility for anything involving the logical contents of
    the database (e.g., managing transaction status information, recovery
    conflicts, considering what to do with HOT chains).  Index vacuuming and
    heap vacuuming are now only concerned with recycling garbage items from
    physical data structures that back the logical database.
    
    Bump XLOG_PAGE_MAGIC due to pruning and heap page vacuum WAL record
    changes.
    
    Credit for the idea of retrying pruning a page to avoid the tupgone case
    goes to Andres Freund.
    
    Author: Peter Geoghegan <pg@bowt.ie>
    Reviewed-By: default avatarAndres Freund <andres@anarazel.de>
    Reviewed-By: default avatarMasahiko Sawada <sawada.mshk@gmail.com>
    Discussion: https://postgr.es/m/CAH2-WznneCXTzuFmcwx_EyRQgfsfJAAsu+CsqRFmFXCAar=nJw@mail.gmail.com
    8523492d
heapdesc.c 6.52 KB