From 3b4c9a890fdeb854949a36b6be8f1fc00a5edafe Mon Sep 17 00:00:00 2001 From: Zhijie Hou Date: Fri, 10 Apr 2026 16:24:55 +0800 Subject: [PATCH v1] Allow old WALs to be removed during REPACK CONCURRENTLY --- src/backend/commands/repack_worker.c | 14 +++++++++++++- src/backend/replication/logical/logical.c | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/repack_worker.c b/src/backend/commands/repack_worker.c index 5bd020e0184..50f000ca6df 100644 --- a/src/backend/commands/repack_worker.c +++ b/src/backend/commands/repack_worker.c @@ -394,12 +394,24 @@ decode_concurrent_changes(LogicalDecodingContext *ctx, /* * If WAL segment boundary has been crossed, inform the decoding - * system that the catalog_xmin can advance. + * system that the slot can advance. + * + * Once REPACK begins copying data to the new table, the logical + * decoding machinery prevents the slot from advancing beyond the + * oldest running transaction (which is the REPACK transaction + * itself). As a result, restart_lsn and catalog_xmin can no longer + * advance automatically. + * + * To allow old WAL files to be recycled, we manually advance the + * slot each time a WAL segment boundary is crossed. We do not + * advance catalog_xmin here because the REPACK transaction anyway + * holds a snapshot that prevents catalog tuple removal. */ end_lsn = ctx->reader->EndRecPtr; XLByteToSeg(end_lsn, segno_new, wal_segment_size); if (segno_new != repack_current_segment) { + LogicalIncreaseRestartDecodingForSlot(end_lsn, end_lsn); LogicalConfirmReceivedLocation(end_lsn); elog(DEBUG1, "REPACK: confirmed receive location %X/%X", (uint32) (end_lsn >> 32), (uint32) end_lsn); diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index d8e02c53558..baa639835f7 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -1913,8 +1913,10 @@ LogicalConfirmReceivedLocation(XLogRecPtr lsn) SpinLockRelease(&MyReplicationSlot->mutex); ReplicationSlotsComputeRequiredXmin(false); - ReplicationSlotsComputeRequiredLSN(); } + + if (updated_restart) + ReplicationSlotsComputeRequiredLSN(); } else { -- 2.53.0.windows.2