| From: | solai v <solai(dot)cdac(at)gmail(dot)com> |
|---|---|
| To: | Paul Kim <mok03127(at)gmail(dot)com> |
| Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: [PATCH v1] Add vacuum_delay_point() to GiST empty-page deletion pass |
| Date: | 2026-07-27 19:25:11 |
| Message-ID: | CAF0whuc=E4xoj-zgKuqU51NWOfjA81Dk4rS14TfsJPBf_skwPQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi all,
On Tue, Jul 28, 2026 at 12:16 AM Paul Kim <mok03127(at)gmail(dot)com> wrote:
>
> Hi,
>
> While comparing the vacuum loops of the various index AMs I noticed that
> gistvacuum_delete_empty_pages() -- the second pass of a GiST vacuum that
> unlinks empty leaf pages -- does not call vacuum_delay_point(), even
> though it reads a buffer and issues WAL-logged page deletions for every
> internal page it revisits. The other page-scanning loops in
> gistvacuum.c, gistvacuumscan() and the recursion in gistvacuumpage(),
> both call it.
>
> As a result this phase of a GiST vacuum ignores the cost-based vacuum
> delay entirely, and only reacts to query cancellation when a buffer read
> happens to perform I/O. On a large GiST index with many emptied leaf
> pages this loop can end up walking every internal page of the index.
>
> The attached patch adds a single vacuum_delay_point(false) at the top of
> the loop, where no buffer lock is held, matching the sibling idiom. The
> function has lacked the call since it was introduced in 7df159a620b.
>
> This is long-standing rather than a recent regression, so I'll leave the
> question of back-patching to a committer. Note that on branches before
> 18 vacuum_delay_point() takes no argument (the bool was added by
> e5b0b0ce150), so a back-patch would drop the "false".
>
Thank you for the patch. I reviewed and tested the v1 patch. I was
able to reproduce the execution path by creating a large GiST index,
deleting most of the tuples to generate empty pages, and running
VACUUM (VERBOSE). The cleanup phase entered
gistvacuum_delete_empty_pages(), and with temporary instrumentation in
the function gistvacuum_delete_empty_pages() in gistvacuum.c. I
confirmed that the newly added vacuum_delay_point(false) is invoked
repeatedly while scanning internal pages.
VACUUM (VERBOSE) t;
index scan needed: 63058 pages from table (99.00% of total) had
9900000 dead item identifiers removed
index "gist_idx": pages: 54352 in total, 53224 newly deleted, 53224
currently deleted, 0 reusable
Logfile:
LOG: checkpoint starting: wal
LOG: Entered gistvacuum_delete_empty_pages
CONTEXT: while cleaning up index "gist_idx" of relation "public.t"
STATEMENT: VACUUM (VERBOSE) t;
LOG: Called vacuum_delay_point() in GiST empty-page deletion
The patch ensures that the empty-page deletion pass now periodically
invokes vacuum_delay_point(), making its behavior consistent with
other long-running VACUUM loops. I did not observe any functional
issues or regressions during testing. The patch looks good to me.
Regards,
Solai
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Chauhan Dhruv | 2026-07-27 19:27:43 | Expression index can get an empty generated column name |
| Previous Message | Masahiko Sawada | 2026-07-27 19:20:13 | Re: Fix race condition in pg_get_publication_tables with concurrent DROP TABLE |