Re: Allow aggressive VACUUM to freeze without a cleanup lock

From: Jingtang Zhang <mrdrivingduck(at)gmail(dot)com>
To: Melanie Plageman <melanieplageman(at)gmail(dot)com>
Cc: Yuhang Qiu <iamqyh(at)gmail(dot)com>, Peter Geoghegan <pg(at)bowt(dot)ie>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Allow aggressive VACUUM to freeze without a cleanup lock
Date: 2026-08-27 16:46:01
Message-ID: CAPsk3_DtWy+-JZBVE9A-Kga-+E_ra3RK=9X28301JtnaH95+Pw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi, Melanie.

Thanks for looking.

> Do you know if in your use case this would have been able to do the
> freeze (i.e. you didn't have too-old dead tuples on the page) with
> needing pruning?

In this case, I believe the page would have been able to make freeze
progress without pruning. Whenever an anti-wraparound VACUUM became
stuck, we had to terminate every SELECT FOR UPDATE session accessing that
page before it could acquire the cleanup lock and proceed past the page
using the normal prune-and-freeze path. That pass would have removed any
removable DEAD tuples on the page. Across many subsequent
anti-wraparound VACUUM runs, the same page and the same row repeatedly
became the blocking point again. The recurring workload continuously
ran SELECT FOR UPDATE on that row, and later anti-wraparound VACUUM runs
again waited on BufferPin at the same page and row.

SELECT FOR UPDATE does not create a new tuple version. It only locks
the existing tuple, so repeated locking of the same logical row continues
to access the same physical tuple and the same heap page. There is no
mechanism that moves this hotspot to another page.

UPDATE behaves differently. Without pruning, old tuple versions cannot
have their space recycled on the current page. As the page fills, a
later update can no longer be HOT and must place the new current version
on another page. The original page is then no longer the hotspot for
that row, so the sustained pins can move away and it can get a chance to
be pruned. SELECT FOR UPDATE has no comparable escape path.

---
Regards,
Jingtang

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2026-08-27 16:47:51 Re: REPACK (CONCURRENTLY) backend waits indefinitely when decoding worker fails to start
Previous Message Nathan Bossart 2026-08-27 16:43:37 REPACK decoding worker startup/teardown differs from parallel.c