[Patch]The Case For WAL-Logging pg_upgrade

Started by Bohyun Lee3 days ago3 messageshackers
Jump to latest
#1Bohyun Lee
bohyun.lee@databricks.com

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
<https://github.com/LeeBohyun/postgres/tree/wal-upgrade-patch&gt;

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

Attachments:

v1-wal-upgrade.patchapplication/octet-stream; name=v1-wal-upgrade.patchDownload+7871-89
#2John Naylor
john.naylor@enterprisedb.com
In reply to: Bohyun Lee (#1)
Re: [Patch]The Case For WAL-Logging pg_upgrade

On Fri, Jul 31, 2026 at 8:14 PM Bohyun Lee <bohyun.lee@databricks.com> wrote:

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.

This is an interesting proposal. I think a new RMGR that ships a
filesystem transformation through the WAL stream might be a difficult
sell. It's different in that the system must know what file paths to
stick into the WAL stream to get the desired result. It also changes a
lot of the backend to support new capabilities in a frontend tool. If
we're changing this much in the tree, we have other options to arrange
for normal WAL to physically propagate the primary's changes, since
that's a desireable feature. Coincidentally, I've been prototyping
ideas lately as well.

--
John Naylor
Amazon Web Services

#3Bohyun Lee
bohyun.lee@databricks.com
In reply to: John Naylor (#2)
Re: [Patch]The Case For WAL-Logging pg_upgrade

Hi John,

Thank you for sharing your thoughts and providing this context.

If you're referring to relinking user relations with filesystem primitives
during the upgrade (the XLOG_UPGRADE_RELINK manifest), that redo path
reproduces exactly what pg_upgrade already does for each transfer
mode—link(), copyfile()/FICLONE, copy_file_range(), copy_file(), and
rename(). Upstream already performs bulk filesystem transformations today:
--link hardlinks every user relation, --clone reflinks them, and --swap
renames whole database directories. Therefore, the transformation itself
isn't new; what changes is where it happens.

The RELINK WAL record also doesn't contain paths: entries carry
(tablespace_oid, database_oid, relfilenumber, forknum, segno), and redo
derives the path in the same form as xl_dbase_create_file_copy_rec. Only
DIRTREE and RAWFILE carry paths.

I take the layering concern to be the more substantive one, and I don't
think "the primitives are upstream's" answers it.

Could you say more about the other options you have in mind and share your
prototype if it's shareable? I'd be glad to work in that direction if that
would provide a better foundation.

Best regards,

Bohyun

On Sat, Aug 1, 2026 at 2:31 AM John Naylor <johncnaylorls@gmail.com> wrote:

Show quoted text

On Fri, Jul 31, 2026 at 8:14 PM Bohyun Lee <bohyun.lee@databricks.com>
wrote:

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.

This is an interesting proposal. I think a new RMGR that ships a
filesystem transformation through the WAL stream might be a difficult
sell. It's different in that the system must know what file paths to
stick into the WAL stream to get the desired result. It also changes a
lot of the backend to support new capabilities in a frontend tool. If
we're changing this much in the tree, we have other options to arrange
for normal WAL to physically propagate the primary's changes, since
that's a desireable feature. Coincidentally, I've been prototyping
ideas lately as well.

--
John Naylor
Amazon Web Services