pgsql: Do not take a full-page image for REGBUF_NO_CHANGE buffers

From: Michael Paquier <michael(at)paquier(dot)xyz>
To: pgsql-committers(at)lists(dot)postgresql(dot)org
Subject: pgsql: Do not take a full-page image for REGBUF_NO_CHANGE buffers
Date: 2026-10-29 02:15:12
Message-ID: E1xMFfc-00000001C4s-3iXc@gemulon.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Do not take a full-page image for REGBUF_NO_CHANGE buffers

A buffer registered with REGBUF_NO_CHANGE is not modified by the record
and, in the case of the hash index AM, may be held with only a pin (no
content lock). The hash index code registers the primary bucket page
this way in hashbucketcleanup(), _hash_freeovflpage() and
_hash_squeezebucket(), solely to force a cleanup lock on that block
during replay.

When wal_consistency_checking includes "hash", XLogRecordAssemble()
included a full-page image for block only pinned, because
XLR_CHECK_CONSISTENCY forces an image regardless of REGBUF_NO_IMAGE.
The record CRC is then computed over the image while a concurrent
backend, which legitimately holds nothing stronger than a pin
on that page, could modify it before the record is copied into the WAL
buffers. This would result is an intermittent "incorrect resource
manager data checksum in record" failure on a standby.

As of this commit, never take an image for a REGBUF_NO_CHANGE buffer,
even under XLR_CHECK_CONSISTENCY. There is no need to do a consistency
check on a block not changed by a record. verifyBackupPageConsistency()
is taught to skip a registered block that carries no image rather than
asserting one should be present.

REGBUF_NO_CHANGE exists since 00d7fb5e2e39, so backpatch down to v17.
On older branches, the CRC problem can be reproduced as well, but we
lack the mechanism to check how a buffer is handled by the code
assembling a record. Per discussion, the long term picture should be to
fix the hash index AM so as REGBUF_NO_CHANGE is removed. This would be
a HEAD-only change.

Reported-by: Alexander Lakhin <exclusion(at)gmail(dot)com>
Diagnosed-by: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>
Author: Greg Burd <greg(at)burd(dot)me>
Discussion: https://postgr.es/m/ats4pi-RM0Uom0T9@floki
Backpatch-through: 17

Branch
------
REL_17_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/fd1f61e435114f90cef15a7573f37b6b9e6256a9

Modified Files
--------------
src/backend/access/transam/README | 5 +++++
src/backend/access/transam/xloginsert.c | 7 ++++++-
src/backend/access/transam/xlogrecovery.c | 7 ++++++-
src/include/access/xloginsert.h | 4 +++-
4 files changed, 20 insertions(+), 3 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Richard Guo 2026-10-29 02:30:05 pgsql: Don't replace clone clauses with constant TRUE
Previous Message Amit Langote 2026-10-29 01:39:56 pgsql: Fix JSON_TABLE with sublinks in PASSING arguments