Hi The recent support for dynamic toggling of logical decoding (67c2097) disables logical decoding if no logical slots are present. But the repack command doesn't seem to coordinate with this toggling. The effective_wal_level is not decreasing after using repack concurrently.
postgres=# show effective_wal_level; effective_wal_level --------------------- replica (1 row) postgres=# create table foo(a int primary key); CREATE TABLE postgres=# REPACK (CONCURRENTLY) foo; 2026-05-21 20:46:25.423 PKT [1591896] LOG: logical decoding is enabled upon creating a new logical replication slot 2026-05-21 20:46:25.634 PKT [1591896] LOG: logical decoding found consistent point at 0/018F36D0 2026-05-21 20:46:25.634 PKT [1591896] DETAIL: There are no running transactions. REPACK postgres=# select slot_name from pg_replication_slots; slot_name ----------- (0 rows) postgres=# show effective_wal_level; effective_wal_level --------------------- logical (1 row) The server has to be restarted in order to decrease the effective_wal_level. REPACK CONCURRENTLY uses a temporary slot that is dropped at the time of cleanup, but logical decoding is not disabled. This may be related to both commits, 28d534e and 67c2097 The attached patch adds the `RequestDisableLogicalDecoding` call to `repack_cleanup_logical_decoding` after the replication slot is dropped so the checkpointer will take care of it.. Thanks Imran Zaheer
From 8a124aaae31612a19cb38434e8612162b6ae76ff Mon Sep 17 00:00:00 2001 From: Imran Zaheer <[email protected]> Date: Thu, 21 May 2026 20:55:11 +0500 Subject: [PATCH v1] Disable logical decoding after REPACK (CONCURRENTLY) effective WAL level should be decreased after `REPACK (CONCURRENTLY)` if necessary. Request to disable logical decoding automatically during repack cleanup. --- src/backend/commands/repack_worker.c | 3 +++ src/test/recovery/t/051_effective_wal_level.pl | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/backend/commands/repack_worker.c b/src/backend/commands/repack_worker.c index b84041372b8..276f5d4fd9a 100644 --- a/src/backend/commands/repack_worker.c +++ b/src/backend/commands/repack_worker.c @@ -324,6 +324,9 @@ repack_cleanup_logical_decoding(LogicalDecodingContext *ctx) FreeDecodingContext(ctx); ReplicationSlotDropAcquired(); + + /* Checkpointer will disable the decoding if necessary */ + RequestDisableLogicalDecoding(); } /* diff --git a/src/test/recovery/t/051_effective_wal_level.pl b/src/test/recovery/t/051_effective_wal_level.pl index c4c2662f72b..663ed730c91 100644 --- a/src/test/recovery/t/051_effective_wal_level.pl +++ b/src/test/recovery/t/051_effective_wal_level.pl @@ -141,6 +141,20 @@ test_wal_level($primary, "replica|replica", "effective_wal_level got decreased to 'replica' after invalidating the last logical slot" ); +# Logical decoding should be disabled after repacking +$primary->safe_psql('postgres', qq[create table foo(a int primary key)]); +$primary->safe_psql('postgres', qq[repack (concurrently) foo;]); +ok( $primary->log_contains( + "logical decoding is enabled upon creating a new logical replication slot" + ), + "logical decoding has been enabled upon creating a temp slot"); + +# Wait for the checkpointer to disable logical decoding. +wait_for_logical_decoding_disabled($primary); +test_wal_level($primary, "replica|replica", + "effective_wal_level got decreased to 'replica' after the REPACK (CONCURRENTLY) command" +); + # Revert the modified settings, and restart the server. $primary->adjust_conf('postgresql.conf', 'max_slot_wal_keep_size', undef); $primary->adjust_conf('postgresql.conf', 'min_wal_size', undef); -- 2.34.1
