Re: [Patch]The Case For WAL-Logging pg_upgrade

From: Hüseyin Demir <huseyin(dot)d3r(at)gmail(dot)com>
To: Bohyun Lee <bohyun(dot)lee(at)databricks(dot)com>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: [Patch]The Case For WAL-Logging pg_upgrade
Date: 2026-08-12 12:49:19
Message-ID: CAB5wL7ag8VA-3PDXwgeRDj+uQhnydFtbovBtDVT0ud2YXJwo-g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi there,

Thanks for the amazing work. Appreciate the idea and initial proposal.

I approach this patch from two different angles and views. I suppose
the idea is that our pg_upgrade can do better and provide a smooth
experience. I've been working on upgrading many clusters currently.

Some feedback about the patch

SGML docs describe `--wal-upgrade-rollback` and
`--wal-upgrade-delete-old` as working options, but code doesn't
implement them. It would be nice if you can update the docs or
implement the subcommands.

Secondly, maybe you need literal string values in
pg_upgrade_standby_transfer_mode GUC.

When it comes to operational concerns

The operator must manually configure `pg_upgrade_standby_old_datadir`
on every replica. With 10+ replicas across multiple machines, this
requires a manual effort and introduces additional failures during the
upgrade and no validation until RELINK redo (late failure). Maybe we
should introduce a helper to validate before upgrading.

If replicas have a different tablespace layout than the primary,
RELINK redo will probably fail. RELINK redo only contains relative
paths (base/12345/16384, pg_tblspc/16389/...) and assumes:

1. The operator knows which old paths are which tablespaces
2. The old data is all at `pg_upgrade_standby_old_datadir`
3. Custom tablespaces use standard `pg_tblspc/` symlink structure

The patch only documents the "upgrade an existing replica" scenario.
Cascading replicas are not addressed.

Current approach doesn't cover the case once a burst server crashes
before finalizing the upgrade. The operator has to re-run the entire
upgrade process. We need to improve documentation or improve the
behavior.

I also have other concerns but wanted to start with these first.

Regards,
Demir.

Bohyun Lee <bohyun(dot)lee(at)databricks(dot)com>, 31 Tem 2026 Cum, 15:14
tarihinde şunu yazdı:
>
> Hi all,
>
>
> I would like to propose a patch that WAL-logs pg_upgrade.
>
>
> The detailed proposal including the workflow and a real use case, etc. is available in the GitHub branch below:
>
> https://github.com/LeeBohyun/postgres/blob/wal-upgrade-patch/The_Case_For_WAL-Logging_pg_upgrade.pdf
>
>
> Below is a brief summary of the proposal.
>
> ____________________________________________________________________________________
>
>
> Problem of stock pg_upgrade.
>
> Current pg_upgrade writes the files of the new cluster directly, emitting no WAL for the changes it makes. This creates two fundamental limitations.
>
>
> The first is a replication gap. Since the upgrade never enters the WAL stream, standbys cannot adopt it through replication and must be taken offline and resynchronized from the primary via rsync.
>
>
> The second is a durability gap in the backup chain. The upgraded cluster begins with a new WAL history that is disconnected from the history of the old cluster. Consequently, if the upgraded primary fails before a new base backup is taken, transactions committed after the upgrade cannot be recovered. This window may remain open for a long time, if the database is large and taking a backup requires a long time.
>
>
>
> Closing replication and durability gaps.
>
> The patch closes both gaps by atomically WAL-logging the after-images generated by pg_upgrade upon successful completion. The upgrade becomes part of the WAL stream and can be propagated to standbys through standard streaming replication, eliminating the need for offline rsync-based resynchronization.
>
>
> Furthermore, because the upgraded cluster continues the existing WAL history rather than creating a new one, the upgrade and all subsequent modifications remain recoverable through WAL replay, preserving durability even before a new base backup is taken.
>
>
>
> Workflow with primary/standby with the proposed interface.
>
> (1) pg_upgrade --wal-upgrade-signal-handoff triggers the primary to shutdown and standbys to pause.
>
> (2) pg_upgrade --wal-upgrade performs the upgrade
>
> (3) and captures it as WAL.
>
> (4) The primary goes live on restart with the new version.
>
> (5) Each standby comes up on the new version over its retained data directory, streams and replays the upgrade WALs
>
> (6) and becomes a hot standby once the WALs are fully replayed.
>
>
>
> Recovery workflow with primary/backup with the proposed interface.
>
> (1) Restore the last pre-upgrade base backup.
>
> (2) PITR-replay archived WAL up to the upgrade point.
>
> (3) Restart on the new version and replay upgrade WALs.
>
> (4) Keep replaying the new-version WAL to recover the post-upgrade transactions.
>
> (5) Promote, fully recovered without a new base backup.
>
>
>
> Expected benefits. Upgrading a replicated cluster reduces to upgrading the primary with minimal cluster coordination. Standbys catch up by themselves over their existing replication link, without offline rsync or a rebuild. It also guarantees durability of post-upgrade modifications even without a new base backup.
>
> These benefits suggest that perhaps --wal-upgrade should even be the default behavior.
>
> ____________________________________________________________________________________
>
>
> I’ve attached the patch file, and the implementation is in the same repository.
>
> https://github.com/LeeBohyun/postgres/tree/wal-upgrade-patch
>
>
> Any discussion or feedback is welcome, especially from those who run pg_upgrade on PostgreSQL clusters in practice.
>
>
> Best regards,
>
> Bohyun

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Nikhil Sontakke 2026-08-12 12:56:09 Re: Logical replication row filter loses unchanged toasted columns
Previous Message Junwang Zhao 2026-08-12 12:01:26 Re: Fix small psql slash option leaks