pgsql: Fix stale visibility maps in incremental backups after heap trun

From: Fujii Masao <fujii(at)postgresql(dot)org>
To: pgsql-committers(at)lists(dot)postgresql(dot)org
Subject: pgsql: Fix stale visibility maps in incremental backups after heap trun
Date: 2026-11-05 09:09:02
Message-ID: E1xOtSx-00000000Hza-15eA@gemulon.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Fix stale visibility maps in incremental backups after heap truncation

An incremental backup taken after VACUUM truncates a table can restore
stale visibility map bits when both data checksums and wal_log_hints are
disabled. If the restored table grows again, the stale bits can cause
VACUUM to skip required freezing and advance relfrozenxid past unfrozen
tuples, or cause index-only scans to return deleted rows.

Heap truncation clears bits for removed heap pages in the last remaining
VM page. With both settings disabled, that page is not separately
WAL-logged. The WAL summarizer records the VM truncation limit but does
not mark the remaining page as modified, allowing incremental backups
to reuse its old contents. The truncation record precedes the incremental
backup's start LSN, so recovery does not replay it to clear those bits.

Fix this by marking the last remaining VM page as modified when
summarizing a truncation record, so incremental backups include its
current contents. Do this conservatively even when truncation falls on
a VM page boundary and the remaining page does not need to change.

Note that existing WAL summaries are not regenerated by this fix.
Incremental backups taken after updating can therefore still be affected
if they use summaries generated before the fix. Take a new full backup
from an uncorrupted server after updating and use it as the basis for
subsequent incremental backups. This does not repair existing backups
or corruption already present in a restored database.

Backpatch to PostgreSQL 17, where incremental backup was introduced.

Bug: #19775
Author: Ke <kehan5800(at)gmail(dot)com>
Co-authored-by: Fujii Masao <masao(dot)fujii(at)gmail(dot)com>
Co-authored-by: Shihao Zhong <zhong950419(at)gmail(dot)com>
Discussion: https://postgr.es/m/19775-087aebfa1a709b09@postgresql.org
Discussion: https://postgr.es/m/CAGRkXqSnghF+wbyP-PdfjVLfbejJG3cvZd9hN-gxsvCWj2F64Q@mail.gmail.com
Backpatch-through: 17

Branch
------
REL_17_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/0733c72198c9d49b239703a01d9fb5ecba7d04fb

Modified Files
--------------
src/backend/postmaster/walsummarizer.c | 19 +++++-
src/bin/pg_combinebackup/meson.build | 1 +
src/bin/pg_combinebackup/t/014_vm_truncation.pl | 90 +++++++++++++++++++++++++
3 files changed, 108 insertions(+), 2 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Heikki Linnakangas 2026-11-05 11:58:11 pgsql: Use branchless comparisons in btint4cmp and btint8cmp, for speed
Previous Message Fujii Masao 2026-11-05 09:08:53 pgsql: Fix stale visibility maps in incremental backups after heap trun