• Peter Geoghegan's avatar
    Fix bug in nbtree VACUUM "skip full scan" feature. · b0229f26
    Peter Geoghegan authored
    Commit 857f9c36 (which taught nbtree VACUUM to skip a scan of the
    index from btcleanup in situations where it doesn't seem worth it) made
    VACUUM maintain the oldest btpo.xact among all deleted pages for the
    index as a whole.  It failed to handle all the details surrounding pages
    that are deleted by the current VACUUM operation correctly (though pages
    deleted by some previous VACUUM operation were processed correctly).
    
    The most immediate problem was that the special area of the page was
    examined without a buffer pin at one point.  More fundamentally, the
    handling failed to account for the full range of _bt_pagedel()
    behaviors.  For example, _bt_pagedel() sometimes deletes internal pages
    in passing, as part of deleting an entire subtree with btvacuumpage()
    caller's page as the leaf level page.  The original leaf page passed to
    _bt_pagedel() might not be the page that it deletes first in cases where
    deletion can take place.
    
    It's unclear how disruptive this bug may have been, or what symptoms
    users might want to look out for.  The issue was spotted during
    unrelated code review.
    
    To fix, push down the logic for maintaining the oldest btpo.xact to
    _bt_pagedel().  btvacuumpage() is now responsible for pages that were
    fully deleted by a previous VACUUM operation, while _bt_pagedel() is now
    responsible for pages that were deleted by the current VACUUM operation
    (this includes half-dead pages from a previous interrupted VACUUM
    operation that become fully deleted in _bt_pagedel()).  Note that
    _bt_pagedel() should never encounter an existing deleted page.
    
    This commit theoretically breaks the ABI of a stable release by changing
    the signature of _bt_pagedel().  However, if any third party extension
    is actually affected by this, then it must already be completely broken
    (since there are numerous assumptions made in _bt_pagedel() that cannot
    be met outside of VACUUM).  It seems highly unlikely that such an
    extension actually exists, in any case.
    
    Author: Peter Geoghegan
    Reviewed-By: Masahiko Sawada
    Discussion: https://postgr.es/m/CAH2-WzkrXBcMQWAYUJMFTTvzx_r4q=pYSjDe07JnUXhe+OZnJA@mail.gmail.com
    Backpatch: 11-, where the "skip full scan" feature was introduced.
    b0229f26
nbtree.h 44.7 KB