| From: | "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com> |
|---|---|
| To: | 'Greg Burd' <greg(at)burd(dot)me>, vignesh C <vignesh21(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" <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-13 10:21:27 |
| Message-ID: | OS7PR01MB1831738CC51177B1392E379DBF57F2@OS7PR01MB18317.jpnprd01.prod.outlook.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
Thanks for updating the patch. Few more comments. Note that I did not review 0003,
because I was not sure it's intended to be pushed.
01.
```
+ * If buf is an overflow page, the primary bucket page is not
+ * changed and we hold only a pin on it, so it is not
+ * registered. Append its block number instead, and replay
+ * takes a cleanup lock on it. It is not needed otherwise
```
I think we should clarify why the primary bucket itself or block number should be
registered. Idea:
```
/*
* Replay must take a cleanup lock on the primary bucket page to
* serialize with scans on a hot standby. If buf is an overflow
* page, the unchanged primary page is held only by a pin, so append
* its block number instead of registering it. Otherwise block 0
* identifies the primary page.
*/
```
02.
```
+/*
+ * Take a cleanup lock on the primary bucket page of the bucket that a
+ * squeeze or delete record operates on, when that page is not one of the
+ * pages the record changes and so is not registered in it. Its block number
+ * is stored in the main data of the record, right after the fixed-size struct
+ * of rec_size bytes.
+ *
+ * This serializes replay against scans on a hot standby, which pin the
+ * primary bucket page for their whole duration; see the comments in the
+ * callers. The page is not modified, so nothing is done with it besides
+ * locking it. block_id must be a block of the same index registered in
+ * the record.
+ */
+static Buffer
+hash_xlog_lock_primary_bucket(XLogReaderState *record, uint8 block_id, Size rec_size)
```
In contrast this might be too detail, the user of the function might not need
such an info. How about:
```
/*
* Take a cleanup lock on an unregistered primary bucket page, whose
* block number is stored in the record's main data. This serializes
* replay against scans on a hot standby. block_id must identify a
* registered block of the same index.
*/
```
03.
```
+ * Register only the pages this record changes. The primary bucket
+ * page is registered only if it is the write page and is modified;
+ * otherwise we may hold only a pin on it, so append its block number
+ * and replay takes a cleanup lock on it.
```
Same as 01, we can clarify the reason why the primary bucket is needed. Idea:
```
/*
* Replay needs the primary bucket block number to acquire a cleanup
* lock. Register it as block 0 when it is modified; otherwise append
* its block number to the record.
*/
```
Best regards,
Hayato Kuroda
FUJITSU LIMITED
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Jan Nidzwetzki | 2026-11-13 10:31:05 | Re: Prevent object capture in CREATE/ALTER EXTENSION scripts |
| Previous Message | Daniel Gustafsson | 2026-11-13 10:07:24 | Re: ISBN range table |