| From: | Greg Burd <greg(at)burd(dot)me> |
|---|---|
| To: | Hayato Kuroda <kuroda(dot)hayato(at)fujitsu(dot)com>, vignesh C <vignesh21(at)gmail(dot)com>, Joao Rito <joaovictor(dot)rito(at)gmail(dot)com> |
| Cc: | Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, shihao zhong <zhong950419(at)gmail(dot)com>, Michael Paquier <michael(at)paquier(dot)xyz>, Jeff Davis <pgsql(at)j-davis(dot)com>, Alexander Lakhin <exclusion(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: Hash index: stop registering pin-only bucket pages in WAL (remove REGBUF_NO_CHANGE) |
| Date: | 2026-11-14 20:35:52 |
| Message-ID: | avixAaDPV2qV69CS@werk |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hayato, vignesh, Joao,
v12 attached. Same series as v11, with one fix: the new torn-page test
failed CI on 32-bit, and this corrects it. Code is unchanged from v11.
The problem: 061_hash_torn_primary_page built its bucket with fixed row
counts and fixed id ranges (DELETE id > 450, then DELETE id <= 50)
tuned to the 64-bit page layout. On 32-bit an index tuple is smaller,
so more entries fit per page and the id ranges no longer map to the
same pages. The first VACUUM then removed dead entries from the primary
bucket page too, so that page got its own full-page image before the
overflow delete, and the test's premise (an overflow delete is replayed
before the primary page's image) no longer held. It failed on the
32-bit, MinGW and Windows VS jobs; 64-bit passed.
The fix makes the workload independent of how many entries fit on a
page. It deletes exactly the index entries that live on the overflow
pages, read from the index with pageinspect:
DELETE FROM t WHERE ctid IN (
SELECT i.ctid
FROM generate_series(1, pg_relation_size('t_i') / block_size - 1) b
CROSS JOIN LATERAL hash_page_items(get_raw_page('t_i', b)) i
WHERE hash_page_type(get_raw_page('t_i', b)) = 'overflow');
So VACUUM removes dead entries only from the overflow chain, never from
the primary bucket page, and the overflow delete is logged with the
primary page held pin-only. The squeeze that follows is the first record
to change the primary page since the backup checkpoint, so it carries
the image that repairs the torn page on replay. The table now uses a
single key column with heap fillfactor 100, and the empty table is
vacuumed before the index is built so hashbuild() starts with the
minimum two buckets; both keep the layout fixed across architectures.
The expected live-row count is read from the table rather than
hardcoded. 062 already used this pattern and passed on 32-bit.
The same change is in the REL15..REL19 back-branch patches, which ship
their own copy of the test.
0001 (the torn-page redo fix) stands alone and is back-patchable;
0002-0004 are master only.
-greg
| Attachment | Content-Type | Size |
|---|---|---|
| v12-0004-Remove-REGBUF_NO_CHANGE.patch | text/x-patch | 5.2 KB |
| v12-0001-Fix-hash-index-redo-reading-a-torn-primary-bucke.patch | text/x-patch | 18.1 KB |
| v12-0002-Don-t-register-pin-only-primary-bucket-pages-in-.patch | text/x-patch | 25.2 KB |
| v12-0003-Add-a-recovery-test-for-the-hash-WAL-pin-only-bu.patch | text/x-patch | 12.0 KB |
| back-patches.tgz.nocfbot | application/octet-stream | 7.4 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Lukas Fittl | 2026-11-14 20:50:41 | Re: [PATCH] auto_explain: preserve per-query sampling decisions (#19877) |
| Previous Message | Noah Misch | 2026-11-14 18:34:54 | Re: reindexdb: Change quoting rule of --schema? |