From b611e157862cce7bd9b141427dcc30d8a26e5d6c Mon Sep 17 00:00:00 2001
From: Paul Kim <mok03127@gmail.com>
Date: Tue, 21 Jul 2026 18:30:41 +0900
Subject: [PATCH v1] Add vacuum_delay_point() to GiST empty-page deletion pass

gistvacuum_delete_empty_pages() rescans the index's internal pages to
unlink the empty leaf pages found during the main vacuum scan.  For each
internal page it reads a buffer and may perform WAL-logged page
deletions, but the loop never calls vacuum_delay_point().  This phase of
a GiST vacuum therefore ignores the cost-based vacuum delay, unlike the
other page-scanning loops in this file: gistvacuumscan() calls
vacuum_delay_point() at the top of its per-page loop, and gistvacuumpage()
calls it before re-reading a buffer when it recurses to an earlier page.

Add vacuum_delay_point(false) at the top of the loop, where no buffer
lock is held, matching the sibling idiom.  vacuum_delay_point() also
checks for interrupts, so this additionally lets the pass respond to
query cancellation without having to wait for a buffer read to perform
I/O.

gistvacuum_delete_empty_pages() has lacked this since it was introduced
in commit 7df159a620b.
---
 src/backend/access/gist/gistvacuum.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c
index 686a0418054..6637b60d600 100644
--- a/src/backend/access/gist/gistvacuum.c
+++ b/src/backend/access/gist/gistvacuum.c
@@ -524,6 +524,9 @@ gistvacuum_delete_empty_pages(IndexVacuumInfo *info, GistVacState *vstate)
 		int			ntodelete;
 		int			deleted;
 
+		/* call vacuum_delay_point while not holding any buffer lock */
+		vacuum_delay_point(false);
+
 		buffer = ReadBufferExtended(rel, MAIN_FORKNUM, (BlockNumber) blkno,
 									RBM_NORMAL, info->strategy);
 
-- 
2.50.1 (Apple Git-155)

