Re: Allow wal_log_hints to be changed without restart

From: Tatsuya Kawata <kawatatatsuya0913(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Allow wal_log_hints to be changed without restart
Date: 2026-07-20 04:24:05
Message-ID: CAHza6qegmyONRMZspxYro7hbRtp_UrFShY=hD6x=QEwAydumrw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Bertrand-san,

> As f19c0ecca introduced online enabling and disabling of data checksums, I
> think that it would make sense to do the same for wal_log_hints.

+1 on the general direction.

> The pg_rewind check on ControlFile->wal_log_hints (which reflects
> the current state at rewind time) remains sufficient.

I'm not sure this holds. In fact, [1] seems to say the opposite:

> It does not really matter if the node used log_hint_bits set to
> false in its latest state (Node to-be-rewinded might have been
> restarted after WAL forked).

What pg_rewind actually requires is that the effective value was
continuously on from the divergence point to the end of the target's
WAL. pg_control only keeps the latest value, so an off period after
the divergence goes undetected:

1. Run with wal_log_hints = off (data checksums off).
2. The standby is promoted (divergence).
3. On the old primary, a hint-bit-only page update happens (not WAL-logged).
4. wal_log_hints is set to on via reload (pg_control now says on).
5. The old primary is cleanly shut down and pg_rewind is run.

The check passes, but the page from step 3 never shows up in
extractPageMap() and is not copied from the source. Combined with the
source's CLOG, the leftover hint bit yields incorrect tuple visibility.

I was able to reproduce this: with a transaction held open across the
divergence (insert before the last common checkpoint, commit after the
divergence), the rewound node shows a row that does not exist on the
source, due to a leftover HEAP_XMIN_COMMITTED hint. I can provide this
as a TAP test. Note that 012_wal_log_hints.pl in the patch exercises
exactly this sequence (diverge while off, reload to on, pg_rewind
succeeds) -- the command succeeds, but the result is not consistent.

Strictly speaking, a similar gap can already be created today by
restarting with a different value, but a reload makes it much easier
to hit.

How about making pg_rewind fail if the WAL range it already scans in
extractPageMap() contains an XLOG_PARAMETER_CHANGE record with
wal_log_hints = off? Current pg_control saying on, plus no change
record in the scanned range, guarantees the value was on for the whole
range. This is essentially the tracking that [1] already suggested on
the pg_rewind side, which does not seem to have been implemented.

[1]
https://postgr.es/m/CAB7nPqSXYs4Jg-KJMy8xiM4sTqkgKvHyDrCoojhXzRSKiW57+g@mail.gmail.com

Regards,
Tatsuya Kawata

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Grigoriy Novikov 2026-07-20 04:34:41 Re: [PATCH] Add cascade synchronous replication
Previous Message Alena Vinter 2026-07-20 02:46:01 Re: pg_rewind WAL segments deletion pitfall