From: Paul Kim <mok03127@gmail.com>
To: pgsql-hackers@lists.postgresql.org
Subject: Restore vacuum_delay_point() in GIN posting-tree leaf vacuum
Date: Sun, 19 Jul 2026 23:27:54 +0900
Message-ID: <178447127453.110.12276981925360691905@mail.gmail.com> (raw)
Hi,
ginVacuumPostingTreeLeaves() sweeps the leaf pages of a GIN posting tree
via their rightlinks, but that loop has no vacuum_delay_point() (and hence
no CHECK_FOR_INTERRUPTS()), unlike the sibling loops in ginbulkdelete() and
ginvacuumcleanup().
The call used to be there: it was dropped when fd83c83d094 rewrote this
cleanup from a recursive walk into the current iterative sweep, and never
re-added to the new loop. That commit was only about fixing a deadlock, so
the removal looks inadvertent.
A posting tree holds all TIDs for a single key, so for a common key it can
span many leaf pages. While one such tree is being vacuumed, the operation
now ignores vacuum_cost_delay and cannot be interrupted (query cancel,
statement_timeout, or autovacuum cancellation when another backend wants a
conflicting lock) until the whole sweep finishes; a corrupted rightlink
forming a cycle turns it into an uninterruptible hang.
The attached patch restores the call, placed where the buffer has already
been released so no content lock is held across the delay. It is against
master; on branches before 18 vacuum_delay_point() takes no argument (the
is_analyze parameter was added by e5b0b0ce150), so the back-branch version
is just "vacuum_delay_point();".
I left the initial leftmost-descent loop in the same function as-is, since
it mirrors the entry-tree descent in ginbulkdelete(), which likewise has no
delay point.
Thanks,
Paul
Attachments:
[text/x-patch] v1-0001-Restore-vacuum_delay_point-in-GIN-posting-tree-le.patch (2.2K, ../178447127453.110.12276981925360691905@mail.gmail.com/2-v1-0001-Restore-vacuum_delay_point-in-GIN-posting-tree-le.patch)
download | inline diff:
From d9b5ddb3cb0cfb55d418a09f571a78ee069eb3e1 Mon Sep 17 00:00:00 2001
From: Paul Kim <mok03127@gmail.com>
Date: Sun, 19 Jul 2026 23:08:12 +0900
Subject: [PATCH v1] 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. A corrupted rightlink that forms a cycle makes the loop run
uninterruptibly forever.
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.
Back-patch to all supported branches, which all contain fd83c83d094.
---
src/backend/access/gin/ginvacuum.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.cindex 840543eb664..a0b81a215a9 100644--- a/src/backend/access/gin/ginvacuum.c+++ b/src/backend/access/gin/ginvacuum.c@@ -429,6 +429,8 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno)
if (blkno == InvalidBlockNumber)
break;
+ vacuum_delay_point(false);+
buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno,
RBM_NORMAL, gvs->strategy);
LockBuffer(buffer, GIN_EXCLUSIVE);
--
2.50.1 (Apple Git-155)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: mok03127@gmail.com, pgsql-hackers@lists.postgresql.org
Subject: Re: Restore vacuum_delay_point() in GIN posting-tree leaf vacuum
In-Reply-To: <178447127453.110.12276981925360691905@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox