| 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 |
| 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 |