Re: BUG #19794: Assert in btvacuumcleanup() fails when page counted in pages_free twice

From: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
To: Alexander Lakhin <exclusion(at)gmail(dot)com>, PostgreSQL mailing lists <pgsql-bugs(at)lists(dot)postgresql(dot)org>
Subject: Re: BUG #19794: Assert in btvacuumcleanup() fails when page counted in pages_free twice
Date: 2026-10-25 00:38:09
Message-ID: 0EF5E9CC-E45D-41A8-848E-DFEE61A0EA82@yandex-team.ru
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi Alexander,

On 24 Oct 2026, Alexander Lakhin wrote:
> stats->pages_deleted: 4927, stats->pages_free: 4928

It looks like _bt_pagedel() can delete a page ahead of the physical
scan. If it becomes recyclable before the scan reaches it, both
btvacuumpage() and _bt_pendingfsm_finalize() can count it as free.

0f0cfb494 seems to expose this by making parallel VACUUM workers inherit
PROC_IN_VACUUM. Their xmin previously held back the recycling horizon.
The pending-FSM optimization itself dates to 9dd963ae2534.

Without assertions, pages_deleted - pages_free underflows and stores a
huge btm_last_cleanup_num_delpages in the metapage, prompting an extra
cleanup-only index scan. I don't see an unsafe page reuse here:
_bt_allocbuf() rechecks recyclability under the page lock.

PFA a small fix: only queue pages at or behind scanblkno, matching the
existing pages_deleted accounting. Pages ahead are left to the normal
scan. This may defer recycling some pages until the next VACUUM if they
are not yet recyclable when the scan visits them.

Thank you!

Best regards, Andrey Borodin.

Attachment Content-Type Size
v1-0001-Avoid-counting-deleted-B-tree-pages-as-free-twice.patch application/octet-stream 2.1 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Dilip Kumar 2026-10-25 06:20:57 Re: BUG #19761: btree_gist: "cannot subtract infinite dates" when inserting 'infinity' into a GiST index on date
Previous Message PG Bug reporting form 2026-10-24 22:28:23 BUG #19795: pgoutput: walsender crashes on START_REPLICATION option without a value