postgres.git / summary / log / commit / refs

commit    15fd7a3e2eeb6de915cae6ea30f40a8e9100cbfe
Author:   Alexander Korotkov <akorotkov@postgresql.org>
Date:     Tue Jul 28 08:50:13 2026 +0000

    Restore vacuum_delay_point() in GIN posting-tree leaf vacuum
    
    Commit fd83c83d094 turned the recursive posting-tree cleanup in
    ginVacuumPostingTreeLeaves() into an iterative sweep that follows the
    tree's leaf pages via their rightlinks.  The recursive version called
    vacuum_delay_point() while processing the tree, but that call was removed
    and never re-added to the new loop.  As that commit only set out to fix a
    deadlock, the removal appears to have been unintentional.
    
    Consequently the leaf-page sweep of a single posting tree runs with no
    vacuum_delay_point(), and therefore no CHECK_FOR_INTERRUPTS().  A posting
    tree stores all the TIDs for one indexed key, so for a frequently
    occurring key it can span a large number of leaf pages.  While such a
    tree is being vacuumed the operation ignores vacuum_cost_delay and does
    not respond to query cancellation or statement_timeout; an autovacuum
    worker likewise cannot be interrupted mid-sweep when another backend
    requests a conflicting lock.
    
    Restore the call, placed after the current page has been unlocked and
    released so that no buffer content lock is held across a potential delay
    (cf. 21c27af65fb).  The sibling loops in ginbulkdelete() and
    ginvacuumcleanup() already call vacuum_delay_point() once per page.
    
    Author: Paul Kim <mok03127@gmail.com>
    Co-authored-by: Alexander Korotkov <aekorotkov@gmail.com>
    Reviewed-by: Michael Paquier <michael@paquier.xyz>
    Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
    Reviewed-by: solai v <solai.cdac@gmail.com>
    Discussion: https://postgr.es/m/178447127453.110.12276981925360691905%40mail.gmail.com
    Backpatch-through: 14


src/backend/access/gin/ginvacuum.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index a276eb020b5..ef7b71057ef 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -396,6 +396,13 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno) if (blkno == InvalidBlockNumber) break; + /* + * A safe point to delay/accept interrupts: the previous page has been + * unlocked and released, so we hold no buffer content lock (nor any + * other LWLock) here and CHECK_FOR_INTERRUPTS() can do its job. + */ + vacuum_delay_point(); + buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, RBM_NORMAL, gvs->strategy); LockBuffer(buffer, GIN_EXCLUSIVE); [parent: 55adef7abbe8]