public inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
effective_wal_level is not decreasing after using REPACK (CONCURRENTLY)
4+ messages / 3 participants
[nested] [flat]

* effective_wal_level is not decreasing after using REPACK (CONCURRENTLY)
@ 2026-05-21 16:32 Imran Zaheer <imran.zhir@gmail.com>
  2026-05-22 04:18 ` Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) shveta malik <shveta.malik@gmail.com>
  0 siblings, 1 reply; 4+ messages in thread

From: Imran Zaheer @ 2026-05-21 16:32 UTC (permalink / raw)
  To: pgsql-hackers

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


Attachments:

  [text/x-patch] v1-0001-Disable-logical-decoding-after-REPACK-CONCURRENTL.patch (2.2K, 2-v1-0001-Disable-logical-decoding-after-REPACK-CONCURRENTL.patch)
  download | inline diff:
From 8a124aaae31612a19cb38434e8612162b6ae76ff Mon Sep 17 00:00:00 2001
From: Imran Zaheer <imran.zhir@gmail.com>
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



^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY)
  2026-05-21 16:32 effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) Imran Zaheer <imran.zhir@gmail.com>
@ 2026-05-22 04:18 ` shveta malik <shveta.malik@gmail.com>
  2026-05-22 06:10   ` Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) Masahiko Sawada <sawada.mshk@gmail.com>
  0 siblings, 1 reply; 4+ messages in thread

From: shveta malik @ 2026-05-22 04:18 UTC (permalink / raw)
  To: Imran Zaheer <imran.zhir@gmail.com>; Sawada Masahiko <sawada.mshk@gmail.com>; +Cc: pgsql-hackers; shveta malik <shvetamalik@gmail.com>

On Thu, May 21, 2026 at 10:02 PM Imran Zaheer <imran.zhir@gmail.com> wrote:
>
> 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 for reporting the issue. I agree with both the problem
statement and the proposed fix.

The fix LGTM. The only point I’d like to discuss is whether it would
make more sense for RequestDisableLogicalDecoding() to be called
directly from ReplicationSlotDropAcquired().

Currently, ReplicationSlotRelease(), ReplicationSlotDrop(), and now
repack_cleanup_logical_decoding() all invoke
RequestDisableLogicalDecoding() immediately after
ReplicationSlotDropAcquired(). Given this pattern, it may be cleaner
and less error-prone to make RequestDisableLogicalDecoding() part of
ReplicationSlotDropAcquired() itself, which could also help avoid
similar bugs in the future.

That said, one concern is that ReplicationSlotsDropDBSlots() could end
up issuing too many disable requests if there are many logical slots
in the target database, so I’m not entirely sure whether this is the
right direction. Thoughts?

Copying Sawada-san (author of the original patch) too, to share his
thoughts on this.

thanks
Shveta






^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY)
  2026-05-21 16:32 effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) Imran Zaheer <imran.zhir@gmail.com>
  2026-05-22 04:18 ` Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) shveta malik <shveta.malik@gmail.com>
@ 2026-05-22 06:10   ` Masahiko Sawada <sawada.mshk@gmail.com>
  2026-05-22 08:57     ` Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) shveta malik <shveta.malik@gmail.com>
  0 siblings, 1 reply; 4+ messages in thread

From: Masahiko Sawada @ 2026-05-22 06:10 UTC (permalink / raw)
  To: shveta malik <shveta.malik@gmail.com>; +Cc: Imran Zaheer <imran.zhir@gmail.com>; pgsql-hackers; shveta malik <shvetamalik@gmail.com>

On Thu, May 21, 2026 at 9:19 PM shveta malik <shveta.malik@gmail.com> wrote:
>
> On Thu, May 21, 2026 at 10:02 PM Imran Zaheer <imran.zhir@gmail.com> wrote:
> >
> > 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..
> >

Good catch!

>
> Thanks for reporting the issue. I agree with both the problem
> statement and the proposed fix.
>
> The fix LGTM. The only point I’d like to discuss is whether it would
> make more sense for RequestDisableLogicalDecoding() to be called
> directly from ReplicationSlotDropAcquired().
>
> Currently, ReplicationSlotRelease(), ReplicationSlotDrop(), and now
> repack_cleanup_logical_decoding() all invoke
> RequestDisableLogicalDecoding() immediately after
> ReplicationSlotDropAcquired(). Given this pattern, it may be cleaner
> and less error-prone to make RequestDisableLogicalDecoding() part of
> ReplicationSlotDropAcquired() itself, which could also help avoid
> similar bugs in the future.
>
> That said, one concern is that ReplicationSlotsDropDBSlots() could end
> up issuing too many disable requests if there are many logical slots
> in the target database, so I’m not entirely sure whether this is the
> right direction. Thoughts?

Good point. I think we can have ReplicationSlotDropAcquired() have a
flag to skip sending a deactivation request. That way,
ReplicationSlotsDropDBSlots() can check the logical slot presence
after processing all slots and other callers can request the
deactivation after dropping the slot. It would help simplify the code
somewhat. It's conventional that when dropping a slot we acquire the
slot first and call RepicationSlotDropAcquired() to reliably drop a
slot (ReplicationSlotCleanup() is an exception). Therefore, I think
that having a flag to ReplicationSlotDropAcquired() could help future
developers to make sure to disable logical decoding at the slot drop.

Regards,

-- 
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com






^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY)
  2026-05-21 16:32 effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) Imran Zaheer <imran.zhir@gmail.com>
  2026-05-22 04:18 ` Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) shveta malik <shveta.malik@gmail.com>
  2026-05-22 06:10   ` Re: effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) Masahiko Sawada <sawada.mshk@gmail.com>
@ 2026-05-22 08:57     ` shveta malik <shveta.malik@gmail.com>
  0 siblings, 0 replies; 4+ messages in thread

From: shveta malik @ 2026-05-22 08:57 UTC (permalink / raw)
  To: Masahiko Sawada <sawada.mshk@gmail.com>; +Cc: Imran Zaheer <imran.zhir@gmail.com>; pgsql-hackers; shveta malik <shvetamalik@gmail.com>

On Fri, May 22, 2026 at 11:40 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:
>
> On Thu, May 21, 2026 at 9:19 PM shveta malik <shveta.malik@gmail.com> wrote:
> >
> > On Thu, May 21, 2026 at 10:02 PM Imran Zaheer <imran.zhir@gmail.com> wrote:
> > >
> > > 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..
> > >
>
> Good catch!
>
> >
> > Thanks for reporting the issue. I agree with both the problem
> > statement and the proposed fix.
> >
> > The fix LGTM. The only point I’d like to discuss is whether it would
> > make more sense for RequestDisableLogicalDecoding() to be called
> > directly from ReplicationSlotDropAcquired().
> >
> > Currently, ReplicationSlotRelease(), ReplicationSlotDrop(), and now
> > repack_cleanup_logical_decoding() all invoke
> > RequestDisableLogicalDecoding() immediately after
> > ReplicationSlotDropAcquired(). Given this pattern, it may be cleaner
> > and less error-prone to make RequestDisableLogicalDecoding() part of
> > ReplicationSlotDropAcquired() itself, which could also help avoid
> > similar bugs in the future.
> >
> > That said, one concern is that ReplicationSlotsDropDBSlots() could end
> > up issuing too many disable requests if there are many logical slots
> > in the target database, so I’m not entirely sure whether this is the
> > right direction. Thoughts?
>
> Good point. I think we can have ReplicationSlotDropAcquired() have a
> flag to skip sending a deactivation request. That way,
> ReplicationSlotsDropDBSlots() can check the logical slot presence
> after processing all slots and other callers can request the
> deactivation after dropping the slot. It would help simplify the code
> somewhat. It's conventional that when dropping a slot we acquire the
> slot first and call RepicationSlotDropAcquired() to reliably drop a
> slot (ReplicationSlotCleanup() is an exception). Therefore, I think
> that having a flag to ReplicationSlotDropAcquired() could help future
> developers to make sure to disable logical decoding at the slot drop.
>

Yes, that seems like a good proposal. Having an explicit argument
would require authors to consciously review and decide whether logical
decoding should be disabled based on their specific use case. That
would help prevent such bugs from being introduced unintentionally.

thanks
Shveta






^ permalink  raw  reply  [nested|flat] 4+ messages in thread


end of thread, other threads:[~2026-05-22 08:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-05-21 16:32 effective_wal_level is not decreasing after using REPACK (CONCURRENTLY) Imran Zaheer <imran.zhir@gmail.com>
2026-05-22 04:18 ` shveta malik <shveta.malik@gmail.com>
2026-05-22 06:10   ` Masahiko Sawada <sawada.mshk@gmail.com>
2026-05-22 08:57     ` shveta malik <shveta.malik@gmail.com>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox