POC: enable logical decoding when wal_level = 'replica' without a server restart

Lists: pgsql-hackers
From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2024-12-31 04:44:38
Message-ID: CAD21AoCVLeLYq09pQPaWs+Jwdni5FuJ8v2jgq-u9_uFbcp6UbA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi all,

Logical decoding (and logical replication) are available only when
wal_level = logical. As the documentation says[1], Using the 'logical'
level increases the WAL volume which could negatively affect the
performance. For that reason, users might want to start with using
'replica', but when they want to use logical decoding they need a
server restart to increase wal_level to 'logical'. My goal is to allow
users who are using 'replica' level to use logical decoding without a
server restart. There are other GUC parameters related to logical
decoding and logical replication such as max_wal_senders,
max_logical_replication_workers, and max_replication_slots, but even
if users set these parameters >0, there would not be a noticeable
performance impact. And their default values are already >0. So I'd
like to focus on making only the wal_level dynamic GUC parameter.
There are several earlier discussions[2][3] but no one has submitted
patches unless I'm missing something.

The first idea I came up with is to make the wal_level a PGC_SIGHUP
parameter. However, it affects not only setting 'replica' to 'logical'
but also setting 'minimal' to 'replica' or higher. I'm not sure the
latter case is common and it might require a checkpoint. I don't want
to make the patch complex for uncommon cases.

The second idea is to somehow allow both WAL-logging logical info and
logical decoding even when wal_level is 'replica'. I've attached a PoC
patch for that. The patch introduces new SQL functions such as
pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
These functions are available only when wal_level is 'repilca'(or
higher). In pg_activate_logical_decoding(), we set the status of
logical decoding stored on the shared memory from 'disabled' to
'xlog-logical-info', allowing all processes to write logical
information to WAL records for logical decoding. But the logical
decoding is still not allowed. Once we confirm all in-progress
transactions completed, we switch the status to
'logical-decoding-ready', meaning that users can create logical
replication slots and use logical decoding.

Overall, with the patch, there are two ways to enable logical
decoding: setting wal_level to 'logical' and calling
pg_activate_logical_decoding() when wal_level is 'replica'. I left the
'logical' level for backward compatibility and for users who want to
enable the logical decoding without calling that SQL function. If we
can automatically enable the logical decoding when creating the first
logical replication slot, probably we no longer need the 'logical'
level. There is room to discuss the user interface. Feedback is very
welcome.

Regards,

[1] https://www.postgresql.org/docs/devel/runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS
[2] https://www.postgresql.org/message-id/flat/CAKU4AWrv6zuywe1VBv6kwFmtaxyi5XYqpBkAG_B46cp4s4KoSw%40mail.gmail.com
[3] https://www.postgresql.org/message-id/20200608213215.mgk3cctlzvfuaqm6%40alap3.anarazel.de

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

Attachment Content-Type Size
PoC_online_activate_logical_decoding.patch application/octet-stream 31.0 KB

From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-03 13:14:01
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Mon, Dec 30, 2024 at 10:44:38PM -0600, Masahiko Sawada wrote:
> Hi all,
>
> Logical decoding (and logical replication) are available only when
> wal_level = logical. As the documentation says[1], Using the 'logical'
> level increases the WAL volume which could negatively affect the
> performance. For that reason, users might want to start with using
> 'replica', but when they want to use logical decoding they need a
> server restart to increase wal_level to 'logical'. My goal is to allow
> users who are using 'replica' level to use logical decoding without a
> server restart.

Thanks for starting that thread and +1 for the idea!

> The first idea I came up with is to make the wal_level a PGC_SIGHUP
> parameter. However, it affects not only setting 'replica' to 'logical'
> but also setting 'minimal' to 'replica' or higher. I'm not sure the
> latter case is common and it might require a checkpoint. I don't want
> to make the patch complex for uncommon cases.
>
> The second idea is to somehow allow both WAL-logging logical info and
> logical decoding even when wal_level is 'replica'. I've attached a PoC
> patch for that. The patch introduces new SQL functions such as
> pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> These functions are available only when wal_level is 'repilca'(or
> higher). In pg_activate_logical_decoding(), we set the status of
> logical decoding stored on the shared memory from 'disabled' to
> 'xlog-logical-info', allowing all processes to write logical
> information to WAL records for logical decoding. But the logical
> decoding is still not allowed. Once we confirm all in-progress
> transactions completed, we switch the status to
> 'logical-decoding-ready', meaning that users can create logical
> replication slots and use logical decoding.
>
> Overall, with the patch, there are two ways to enable logical
> decoding: setting wal_level to 'logical' and calling
> pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> 'logical' level for backward compatibility and for users who want to
> enable the logical decoding without calling that SQL function. If we
> can automatically enable the logical decoding when creating the first
> logical replication slot, probably we no longer need the 'logical'
> level. There is room to discuss the user interface. Feedback is very
> welcome.

If we don't want to force wal_level = logical to enable logical decoding (your
second idea) then I think that it would be better to "hide" everything behind
logical replication slot creation / deletion. That would mean that having at
least one logical replication slot created would be synonym to "activate logical
decoding" and zero logical replication slot created would be synonym to "deactivate
logical decoding".

That way:

1. an end user don't need to manipulate new functions and would just rely on
replication slots existence
2. we ensure that no extra WAL data is generated if not absolutely "needed"

Thoughts?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: "Euler Taveira" <euler(at)eulerto(dot)com>
To: "Bertrand Drouvot" <bertranddrouvot(dot)pg(at)gmail(dot)com>, "Masahiko Sawada" <sawada(dot)mshk(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-03 14:31:03
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jan 3, 2025, at 10:14 AM, Bertrand Drouvot wrote:
> If we don't want to force wal_level = logical to enable logical decoding (your
> second idea) then I think that it would be better to "hide" everything behind
> logical replication slot creation / deletion. That would mean that having at
> least one logical replication slot created would be synonym to "activate logical
> decoding" and zero logical replication slot created would be synonym to "deactivate
> logical decoding".

I like this idea. The logical replication slot existence already has the
required protections and guarantees (no running transactions from the past while
creating) for logical decoding.

ERROR: logical decoding requires "wal_level" >= "logical"
STATEMENT: select pg_create_logical_replication_slot('test', 'pgoutput');

FATAL: logical replication slot "test" exists, but "wal_level" < "logical"
HINT: Change "wal_level" to be "logical" or higher.

Having said that, you are basically folding 'logical' machinery into 'replica'.
The 'logical' option can still exists but it will be less attractive because it
increases the WAL volume even if you are not using logical replication. I don't
know if the current 'logical' behavior (WAL records for logical decoding even
if there is no active logical replication) has any use case (maybe someone
inspects these extra records for analysis) but one suggestion (separate patch)
is to make 'logical' synonymous with the new 'replica' behavior (logical
decoding capability). This opens the door to remove 'logical' in future
releases (accepted as synonym but not documented).

--
Euler Taveira
EDB https://www.enterprisedb.com/


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Euler Taveira <euler(at)eulerto(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-04 00:32:34
Message-ID: CAD21AoD1p-3FszDeVsMytD=fbpUgT-4kN_RY1U7nOC5wC8E1uQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jan 3, 2025 at 6:31 AM Euler Taveira <euler(at)eulerto(dot)com> wrote:
>
> On Fri, Jan 3, 2025, at 10:14 AM, Bertrand Drouvot wrote:
>
> If we don't want to force wal_level = logical to enable logical decoding (your
> second idea) then I think that it would be better to "hide" everything behind
> logical replication slot creation / deletion. That would mean that having at
> least one logical replication slot created would be synonym to "activate logical
> decoding" and zero logical replication slot created would be synonym to "deactivate
> logical decoding".
>
>
> I like this idea. The logical replication slot existence already has the
> required protections and guarantees (no running transactions from the past while
> creating) for logical decoding.

I agree that it's better behavior.

>
> Having said that, you are basically folding 'logical' machinery into 'replica'.
> The 'logical' option can still exists but it will be less attractive because it
> increases the WAL volume even if you are not using logical replication. I don't
> know if the current 'logical' behavior (WAL records for logical decoding even
> if there is no active logical replication) has any use case (maybe someone
> inspects these extra records for analysis) but one suggestion (separate patch)
> is to make 'logical' synonymous with the new 'replica' behavior (logical
> decoding capability). This opens the door to remove 'logical' in future
> releases (accepted as synonym but not documented).

To enable the logical decoding automatically when the first slot is
created, probably we need to do something like:

1. enable WAL-logging logical info.
2. wait for all running transactions to finish.
3. enable logical decoding, and write a XLOG_LOGICAL_DECODING_STATUS record,
4. create a logical slot
4-1. reserve the WAL and write an XLOG_RUNNING_XACTS record.
4-2. wait for all transactions in the XLOG_RUNNING_XACTS record to
finish during creating the initial snapshot.

That is, we could need to wait for different sets of transactions to
finish (at 2 and 4-2). Which could surprise users since the first slot
creation could have users wait for a longer time. Using the 'logical'
level would avoid such waits.

Also, if we make the 'logical' level synonymous with the new 'replica'
behavior, we need to adjust regression tests as well. In some
regression tests (e.g., ondisk_startup.spec), we create a logical slot
while a transaction is concurrently running. We expect we wait for the
concurrent transaction during the slot creation but with the above
algorithm, we would wait for them to activate logical decoding. So I
agree that making the 'logical' level synonymous with the new
'replica' behavior is done in a separate patch. It would be a good
start to implement the new 'replica' level behavior.

Regards,

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


From: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Euler Taveira <euler(at)eulerto(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-06 11:20:14
Message-ID: CAExHW5vrwcoFRrFG9eZ5t0s-KO3=j0CFn2z=TwSzP1-nXDvv+A@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sat, Jan 4, 2025 at 6:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Fri, Jan 3, 2025 at 6:31 AM Euler Taveira <euler(at)eulerto(dot)com> wrote:
> >
> > On Fri, Jan 3, 2025, at 10:14 AM, Bertrand Drouvot wrote:
> >
> > If we don't want to force wal_level = logical to enable logical decoding (your
> > second idea) then I think that it would be better to "hide" everything behind
> > logical replication slot creation / deletion. That would mean that having at
> > least one logical replication slot created would be synonym to "activate logical
> > decoding" and zero logical replication slot created would be synonym to "deactivate
> > logical decoding".
> >
> >
> > I like this idea. The logical replication slot existence already has the
> > required protections and guarantees (no running transactions from the past while
> > creating) for logical decoding.
>
> I agree that it's better behavior.
>
> >
> > Having said that, you are basically folding 'logical' machinery into 'replica'.
> > The 'logical' option can still exists but it will be less attractive because it
> > increases the WAL volume even if you are not using logical replication. I don't
> > know if the current 'logical' behavior (WAL records for logical decoding even
> > if there is no active logical replication) has any use case (maybe someone
> > inspects these extra records for analysis) but one suggestion (separate patch)
> > is to make 'logical' synonymous with the new 'replica' behavior (logical
> > decoding capability). This opens the door to remove 'logical' in future
> > releases (accepted as synonym but not documented).
>
> To enable the logical decoding automatically when the first slot is
> created, probably we need to do something like:
>
> 1. enable WAL-logging logical info.
> 2. wait for all running transactions to finish.
> 3. enable logical decoding, and write a XLOG_LOGICAL_DECODING_STATUS record,
> 4. create a logical slot
> 4-1. reserve the WAL and write an XLOG_RUNNING_XACTS record.
> 4-2. wait for all transactions in the XLOG_RUNNING_XACTS record to
> finish during creating the initial snapshot.

A naive question: Can we combine step 2 and 4-2 - may be we need to
combine 4-1 and 3 too.

--
Best Wishes,
Ashutosh Bapat


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: Euler Taveira <euler(at)eulerto(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-07 06:32:52
Message-ID: CAD21AoCP_fLhR5UYT69w=d5dpw48ZvG-xSTPZwORTgsOhTLJOg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jan 6, 2025 at 3:20 AM Ashutosh Bapat
<ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
>
> On Sat, Jan 4, 2025 at 6:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Fri, Jan 3, 2025 at 6:31 AM Euler Taveira <euler(at)eulerto(dot)com> wrote:
> > >
> > > On Fri, Jan 3, 2025, at 10:14 AM, Bertrand Drouvot wrote:
> > >
> > > If we don't want to force wal_level = logical to enable logical decoding (your
> > > second idea) then I think that it would be better to "hide" everything behind
> > > logical replication slot creation / deletion. That would mean that having at
> > > least one logical replication slot created would be synonym to "activate logical
> > > decoding" and zero logical replication slot created would be synonym to "deactivate
> > > logical decoding".
> > >
> > >
> > > I like this idea. The logical replication slot existence already has the
> > > required protections and guarantees (no running transactions from the past while
> > > creating) for logical decoding.
> >
> > I agree that it's better behavior.
> >
> > >
> > > Having said that, you are basically folding 'logical' machinery into 'replica'.
> > > The 'logical' option can still exists but it will be less attractive because it
> > > increases the WAL volume even if you are not using logical replication. I don't
> > > know if the current 'logical' behavior (WAL records for logical decoding even
> > > if there is no active logical replication) has any use case (maybe someone
> > > inspects these extra records for analysis) but one suggestion (separate patch)
> > > is to make 'logical' synonymous with the new 'replica' behavior (logical
> > > decoding capability). This opens the door to remove 'logical' in future
> > > releases (accepted as synonym but not documented).

FYI one possible use case of the 'logical' level would be that if we
support retrieving WAL records for logical decoding from somewhere
like restore_command in the future, users would like to keep the
wal_level 'logical' or keep the logical decoding active.

> >
> > To enable the logical decoding automatically when the first slot is
> > created, probably we need to do something like:
> >
> > 1. enable WAL-logging logical info.
> > 2. wait for all running transactions to finish.
> > 3. enable logical decoding, and write a XLOG_LOGICAL_DECODING_STATUS record,
> > 4. create a logical slot
> > 4-1. reserve the WAL and write an XLOG_RUNNING_XACTS record.
> > 4-2. wait for all transactions in the XLOG_RUNNING_XACTS record to
> > finish during creating the initial snapshot.
>
> A naive question: Can we combine step 2 and 4-2 - may be we need to
> combine 4-1 and 3 too.

Yeah, maybe we can somewhat optimize this process. Probably we can do like:

1. create a logical slot.
2. enable WAL-logging logical info.
3. reserve the WAL and write an XLOG_RUNNING_XACTS record.
4. wait for all transactions in the XLOG_RUNNING_XACTS record to
finish during creating the initial snapshot.
4-1. write a XLOG_LOGICAL_DECODING_STATUS record if a process
detects all transactions in the XLOG_RUNNING_XACTS record to finish.

However, we need to note that 4-1 should be done by only one process.
Also, it's a bit weird and concerns to me that the snapbuild
initialization contains the process of activating logical decoding.

Regards,

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


From: Peter Smith <smithpb2250(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-08 07:30:09
Message-ID: CAHut+PtUMOOXmEj=hzcRQybo-5ATiWrReg6w-r8U1AKaxprpaA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi Sawada-San.

FWIW, I also thought it was a good idea suggested by Bertrand [1] to
"hide" everything behind the slot create/delete, and thereby eliminate
the need for user intervention using those new
pg_activate/deactivate_logical_decoding functions.

But, one concern doing it this way is how to prevent a user
(accidentally?) getting themselves into a different replication mode
without realising it? Or say they change the mode and then "forget"
that they did that.

For example, If wal_level=replica and then somebody does CREATE
PUBLICATION/SUBSCRIPTION won't that implicitly enable the logical
decoding and then leave it enabled until all the logical replication
slots are eventually dropped? Now, when the user examines wal_level it
is still going to show 'replica', which could be misleading --- e.g.
how will they even know that they can't really trust that anymore, and
they must also check the pg_get_logical_decoding_status?

At least, there should be some big NOTICE/WARNING logs written
whenever the logical decoding status is getting implicitly changed by
logical replication slot create/delete..

~~~

Meanwhile, although it is premature to give detailed code review
comments for what is still a PoC, during my reading of your patch I
made copious notes for myself, so I thought I might as well post what
I have regardless. See the details below in this post. Ignore, or do
with them as you wish. But, hopefully, a lot of the following feedback
will still be relevant regardless of any design changes.

//////////

Commit message

1.
Patch description is missing

======
GENERAL

2. git apply warning

[postgres(at)CentOS7-x64 oss_postgres_misc]$ git apply
../patches_misc/PoC_online_activate_logical_decoding.patch
../patches_misc/PoC_online_activate_logical_decoding.patch:93: new
blank line at EOF.
+
warning: 1 line adds whitespace errors.

~~~

3. Copyright date

All the new files of this patch have the wrong copyright date (2024
instead of 2025).

~~~

4. Missing documentation

There are missing docs changes, but that is to be expected while the
design is in flux.

~~~

5. Terminology

There are multiple places where similar terms like "active" and
"enabled" and "ready" are being used apparently interchangeably making
it quite confusing. Perhaps it was your intention to convey the idea
that the logical mode might be "enabled" but is not yet "active", but
I didn't think that was the case. Mostly it just seemed arbitrary to
me.

IMO the state starting out as "disabled" should end up as "enabled"
(not "ready").

Meanwhile, the API to change the status is currently called
"activate/deactivate" instead of "enable/disable" (??)

Meanwhile, many/most of the error messages talk about "enabled" (not
"activated" or "ready"). e.g. "logical decoding needs to be enabled to
publish logical changes"

Meanwhile, macros are called 'IsLogicalDecodingActive'; why isn't that
called 'IsLogicalDecodingEnabled'.

~

OTOH, maybe you chose the term "active" because master already had the
macro XLogLogicalInfoActive(). But in that case maybe it should be
saying inactive/active everywhere instead of disabled/enabled/ready...

~~~

6. Typedefs

There are some new typedefs introduced in the new files, So these
should be updated in the typedefs.list file.

~~~

7. Tri-state logical decoding status

Currently there is a tri-state logical decoding status: "disabled" ->
"xlog-logicalinfo" -> "ready"

AFAICT that middle state is just transitory. It is easier for me to
visualize it like:
logical decoding status: "disabled" -> "pending" -> "enabled".

IIUC the "pending" part is when it is just waiting for any running
transaction to complete.

IMO it becomes simpler if you do not make any distinction between WAL
logging and logical decoding ability. E.g. Do not allow logical WAL
logging for that 'middle' transitory state; only allow it after
logical decoding becomes fully activated.

IIUC, it would just a small change to do this:

CURRENT (pseudocode):
XLogLogicalInfoEnabled(void) { return XLogLogicalInfoCtl->status >=
LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO; }

SUGGESTION (pseudocode)
XLogLogicalInfoEnabled(void) { return XLogLogicalInfoCtl->status ==
LOGICAL_DECODING_STATUS_READY; }

======
contrib/test_decoding/t/002_online_activation.pl

8.
+# Copyright (c) 2021-2024, PostgreSQL Global Development Group

/2024/2025/

~~~

9.
+# check if a logical replication slot cannot be craeted while logical

/check/Check/

/cannot/can/

/craeted/created/

~~~

10.
+ok( $stderr =~ /ERROR: logical decoding requires "wal_level" >= "logical"/,
+ "logical replication slot cannot be created while logical
decoding is disableed");

/disableed/disabled/

~~~

11.
+# Activate logical info logging.
+$node->safe_psql('postgres',
+ 'SELECT pg_activate_logical_decoding()');
+$ret = $node->safe_psql('postgres', 'SELECT pg_get_logical_decoding_status()');
+is($ret, 'ready', 'logical decoding gets activated');

Perhaps there should be another "show wal_level" done here to show
that even after logical decoding is enabled, the wal_level remains the
same.

~~~

12.
+$node->safe_psql(
+ 'postgres',
+ q[
+CREATE TABLE test (a int primary key, b int);
+INSERT INTO test values (1, 100), (2, 200);
+UPDATE test SET b = b + 10 WHERE a = 1;
+ ]);
+
+$ret = $node->safe_psql(
+ 'postgres',
+ q[SELECT data FROM
pg_logical_slot_get_changes('regression_slot1', NULL, NULL,
'include-xids', '0', 'skip-empty-xacts', '1');]
+ );
+is($ret, 'BEGIN
+table public.test: INSERT: a[integer]:1 b[integer]:100
+table public.test: INSERT: a[integer]:2 b[integer]:200
+COMMIT
+BEGIN
+table public.test: UPDATE: a[integer]:1 b[integer]:110
+COMMIT', 'logical decoding works fine');
+

There seems to be some comment missing for all this part. I expected
it to say something like "Check that logical decoding is working OK".

======
src/backend/access/heap/heapam.c

13.
- * This is only used in wal_level >= WAL_LEVEL_LOGICAL, and only for catalog
- * tuples.
+ * This is only used when XLogLogicalInfoActive() is true, and only for
+ * catalog tuples.

I felt it would be better to Assert this in the code, instead of just
mentioning it in the function comment.

======
src/backend/access/rmgrdesc/xlogdesc.c

14.
+ else if (info == XLOG_LOGICAL_DECODING_STATUS)
+ {
+ bool logical_decoding;
+
+ memcpy(&logical_decoding, rec, sizeof(bool));
+ appendStringInfoString(buf, logical_decoding ? "true" : "false");
+ }

Should there be some textual context for this bool value, like wal_level has?

SUGGESTION
appendStringInfoString(buf, "logical decoding %s", logical_decoding ?
"true" : "false");

~~~

15.
I noticed there are lots of other descriptions in this function that
are showing the value of 'wal_level' via the static function call:
get_wal_level_string(wal_level).

But, since the wal_level now might be out-of-step with the
logcal_decoding boolean value, shouldn't you be showing the logical
decoding state everywhere too?

e.g. you might have a combination like:
wal_level replica
logical decoding true

======
src/backend/access/transam/xlog.c

BootStrapXLOG:

16.
+ checkPoint.logicalDecoding = false;
checkPoint.wal_level = wal_level;

Shouldn't the default for 'logicalDecoding' be consistent with the
assigned wal_level? It seems strange if it is possible to have a
situation where wal_level = logical but simultaneously logicalDecoding
= false.

~~~

xlog_redo:

17.
+ else if (info == XLOG_LOGICAL_DECODING_STATUS)
+ {
+ bool enabled;

A less generic variable name like "logical_decoding_enabled" might be better.

======
src/backend/commands/publicationcmds.c

CreatePublication:

18.
- if (wal_level != WAL_LEVEL_LOGICAL)
+ if (!XLogLogicalInfoActive())
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("\"wal_level\" is insufficient to publish logical changes"),
- errhint("Set \"wal_level\" to \"logical\" before creating subscriptions.")));
+ errmsg("logical decoding needs to be enabled to publish logical changes"),
+ errhint("Set \"wal_level\" to \"logical\" or activate logical
decoding before creating subscriptions.")));

18a.
/needs to be enabled/must be enabled/

~

18b.
The hint seems less useful than it could be because it does not say
*how* the user can activate logical decoding.

SUGGESTION
Set \"wal_level\" to \"logical\" or use pg_activate_logical_decoding
before creating subscriptions.

======
src/backend/replication/logical/logical.c

CheckLogicalDecodingRequirements:

19.
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("logical decoding on standby requires \"wal_level\" >=
\"logical\" on the primary")));
+ errmsg("logical decoding on standby requires to enable logical
decoding on the primary")));
19a
/requires to enable logical decoding/requires logical decoding to be enabled/

~

19b.
This message is like what was in CreatePublication, so might be better
split into an errmsg and errhint.

e.g.
errmsg("logical decoding on standby requires logical decoding to be
enabled on the primary");
errhint("Set \"wal_level\" to \"logical\" or use
pg_activate_logical_decoding.");

======
src/backend/replication/logical/logicalxlog.c

20. General

Would it be better if all the exposed functions from here used the
common "LogicalXLog" prefix?

These ones do:
- LogicalXlogShmemSize
- LogicalXlogShmemInit

These ones don't:
- StartupLogicalDecodingStatus
- UpdateLogicalDecodingStatus
- XLogLogicalInfoEnabled (this one is backwards)
- IsLogicalDecodingActive

~~~

21.
+ * logicalxlog.c
+ * This module contains the codes for enabling or disabling to include
+ * logical information into WAL records and logical decoding.

/codes/code/

Also, this is worded as if you can set those states independently, but
AFAICT the "logical information into WAL" is just a transition-state
to the LOGICAL_DECODING_STATUS_READY.

SUGGESTION
This module contains code to enable/disable and fetch the logical
decoding status.

~~~

22.
+ * Copyright (c) 2012-2024, PostgreSQL Global Development Group

/2024/2025/

~~~

23.
+XLogLogicalInfoCtlData *XLogLogicalInfoCtl = NULL;

Add blank line above this.

~~~

LogicalXlogShmemSize:

24.
+/*
+ * Initialization of shared memory.
+ */
+
+Size
+LogicalXlogShmemSize(void)
+{
+ return sizeof(XLogLogicalInfoCtlData);
+}

Unnecessary blank line after the function comment.

~~~

LogicalXlogShmemInit:

25.
+void
+LogicalXlogShmemInit(void)

Missing function comment.

~~~

StartupLogicalDecodingStatus:

26.
+/*
+ * This must be called ONCE during postmaster or standalone-backend startup,
+ * before calling StartupReplicationSlots().
+ */
+void
+StartupLogicalDecodingStatus(bool enabled_at_last_checkpoint)

The function comment does not actually say what this function does.
Maybe add a first sentence like:
"Assign the initial LogicalDecodingStatus value."

~~~

27.
+ /*
+ * On standbys, we always start with the status in the last checkpoint
+ * record. If changes of wal_level or logical decoding status is sent from
+ * the primary, we will enable or disable the logical decoding while
+ * replaying the WAL record and invalidate slots if necessary.
+ */

/is sent from/are sent from/

/invalidate/invalidating/

~~~

28.
+ if (!StandbyMode)
+ {
+ /*
+ * Disable logical decoding if replication slots are not available.
+ */
+ if (max_replication_slots == 0)
+ status = LOGICAL_DECODING_STATUS_DISABLED;
+
+ /*
+ * If previously the logical decoding was active but the server
+ * restarted with wal_level < 'replica', we disable the logical
+ * decoding.
+ */
+ if (wal_level < WAL_LEVEL_REPLICA)
+ status = LOGICAL_DECODING_STATUS_DISABLED;
+
+ /*
+ * Setting wal_level to 'logical' immediately enables logical decoding
+ * and WAL-logging logical info.
+ */
+ if (wal_level >= WAL_LEVEL_LOGICAL)
+ status = LOGICAL_DECODING_STATUS_READY;
+ }

28a.
The comment is a bit confusing because it is only talking about
Standby, whereas the code block is all for !StandbyMode.

It would be more easy to read if refactored to put the comment in an
empty code block like below:

if (StandByMode)
{
/*
* On standbys, we always start with the status in the last checkpoint
* record...
* ...
*/
}
else
{
<code>
}

~

28b.
What if the first condition (max_replication_slots is 0) and last
condition (WAL_LEVEL_LOGICAL) are true at the same time? Currently
this initializes the status as READY. Is it OK?

~~~

UpdateLogicalDecodingStatus:

29.
+void
+UpdateLogicalDecodingStatus(bool activate)
+{
+ XLogLogicalInfoCtl->status = activate
+ ? LOGICAL_DECODING_STATUS_READY
+ : LOGICAL_DECODING_STATUS_DISABLED;
+}

29a.
Missing function comment.

~

29b.
IMO the parameter should be in past tense, but I also think should be
called "enabled" (same as what it was called in the extern in
logicalxlog.h)

~~~

XLogLogicalInfoEnabled:

30.
+/*
+ * Is WAL-Logging logical info enabled?
+ */
+bool inline
+XLogLogicalInfoEnabled(void)
+{
+ /*
+ * Use volatile pointer to make sure we make a fresh read of the shared
+ * variable.
+ */
+ volatile XLogLogicalInfoCtlData *ctl = XLogLogicalInfoCtl;
+
+ return ctl->status >= LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO;
+}

How necessary is this function?

I thought that LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO is more like
just a transitory state between LOGICAL_DECODING_STATUS_DISABLED and
LOGICAL_DECODING_STATUS_READY. So in that case, isn't it simpler just
to wait for the READY? e.g. remove this function and just use
IsLogicalDecodingActive() instead?

~~~

do_activate_logical_decoding:

31.
Missing function comment.

~~~

32.
+ /*
+ * Get the latest status of logical info logging. If it's already
+ * activated, quick return.
+ */
+ SpinLockAcquire(&XLogLogicalInfoCtl->mutex);
+ if (XLogLogicalInfoCtl->status >= LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO)
+ {
+ SpinLockRelease(&XLogLogicalInfoCtl->mutex);
+ return;
+ }

32a.
I didn't think the comment should mention "logical info logging" here.

SUGGESTION
Quick return if logical decoding is already activated (or activation
was already requested and is pending).

~

32b.
Related to this, it seems simpler to check condition "if
(XLogLogicalInfoCtl->status > LOGICAL_DECODING_STATUS_DISABLED)"

~~~

33.
+ PG_ENSURE_ERROR_CLEANUP(logical_decoding_activation_abort_callback, 0);
+ {
...
+ }
+ PG_END_ENSURE_ERROR_CLEANUP(logical_decoding_activation_abort_callback, 0);

IIUC, this whole chunk of code lies between the status of
"xlog-logicalinfo" and "ready".

I think it needs a comment something like:
/* Confirm that all in-progress transactions have completed before
logical decoding can be enabled. */

~~~

logical_decoding_activation_abort_callback:

34.
Missing function comment.

~~~

35.
Since this is a callback for the function
do_activate_logical_decoding(), I thought the function should be
slightly renamed to match the caller.

/logical_decoding_activation_abort_callback/activate_logical_decoding_abort_callback/

~~~

36.
IIUC, the status could have reached
LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO before we encountered some
problem trying to get to the READY status, and so reset everything
back to DISABLED. So some (unusable?) logical WAL records could have
been written while in that intermediate state? It is another reason
why I was unsure about the need for the earlier XLogLogicalInfoEnabled
function.

Won't it be simpler to just have a DISABLED and ENABLED state and just
keep the transition phase for internal logic? IOW, make
XLogLogicalInfoEnabled() return true only when READY/ENABLED.

~~~
pg_activate_logical_decoding:

37.
Missing function comment.

~~~

38.
+ if (IsTransactionState() &&
+ GetTopTransactionIdIfAny() != InvalidTransactionId)
+ ereport(ERROR,
+ (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+ errmsg("cannot activate logical decoding in transaction that has
performed writes")));
+
+

Double blank lines.

~~~

39.
+ SpinLockAcquire(&(XLogLogicalInfoCtl->mutex));
+ status = XLogLogicalInfoCtl->status;
+ SpinLockRelease(&(XLogLogicalInfoCtl->mutex));
+
+ if (status == LOGICAL_DECODING_STATUS_READY)
+ PG_RETURN_VOID();

Should have some comment like: "If logical decoding is already enabled
then there is nothing to do."

OTOH, can't all this code be removed, since the top-of-loop code will
do the same thing anyway (I didn't think the extra sleep
prepare/cancel that it is doing was something to worry about).

~~~

40.
+ ConditionVariableSleep(&XLogLogicalInfoCtl->cv,
+ WAIT_EVENT_LOGICAL_DECODING_ACTIVATION);
+
+ continue;

Remove the blank line.

~~~

41.
+ /* Activate logical decoding */
+ do_activate_logical_decoding();

The comment is not helpful because it is practically the same as the
function name.

~~~

pg_deactivate_logical_decoding:

42.
Missing function comment.

~~~

43.
+ /*
+ * Hold ReplicationSlotAllocationLock to prevent slots from newly
+ * being created while deactivating the logical decoding.
+ */
+ LWLockAcquire(ReplicationSlotAllocationLock, LW_SHARED);

/newly being created/being created/

~~~

44.
+ for (int i = 0; i < max_replication_slots; i++)
+ {
+ ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i];
+
+ if (!s->in_use)
+ continue;
+
+ if (SlotIsPhysical(s))
+ continue;
+
+ if (s->data.invalidated != RS_INVAL_NONE)
+ continue;
+
+ valid_logical_slots++;
+ }

IMO it is more natural here to check "if (!SlotIsLogical(s))" instead
of "if (SlotIsPhysical(s))".

~~~

45.
+ if (valid_logical_slots > 0)
+ ereport(ERROR,
+ (errmsg("cannot deactivate logical decoding while having valid
logical replication slots")));

/while having valid logical replication slots/while valid logical
replication slots are present/

~~~

46.
+ if (XLogStandbyInfoActive() && !recoveryInProgress)
+ {
+ bool enabled = false;
+
+ XLogBeginInsert();
+ XLogRegisterData((char *) (&enabled), sizeof(bool));
+
+ XLogInsert(RM_XLOG_ID, XLOG_LOGICAL_DECODING_STATUS);
+ }
+
+ SpinLockAcquire(&(XLogLogicalInfoCtl->mutex));
+ XLogLogicalInfoCtl->status = LOGICAL_DECODING_STATUS_DISABLED;
+ SpinLockRelease(&(XLogLogicalInfoCtl->mutex));

In the pg_activate_logical_decoding function, the assignment of the
status and the writing of the XLog record was done within a critical
section. Why isn't the code doing the same here?

~~~

pg_get_logical_decoding_status:

47.
Missing function comment.

======
src/backend/replication/logical/slotsync.c

ValidateSlotSyncParams:

48.
- if (wal_level < WAL_LEVEL_LOGICAL)
+ if (!XLogLogicalInfoActive())
ereport(ERROR,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("replication slot synchronization requires \"wal_level\" >=
\"logical\""));
+ errmsg("replication slot synchronization requires \"wal_level\" >=
\"logical\" or to activate logical decoding"));

This is another message like what was in CreatePublication, and that
might be better split into an errmsg and errhint.

e.g.
errmsg("replication slot synchronization requires logical decoding to
be enabled");
errhint("Set \"wal_level\" to \"logical\" or use
pg_activate_logical_decoding.");

======
src/backend/replication/slot.c

RestoreSlotFromDisk:

49.
+ if (cp.slotdata.database != InvalidOid && !XLogLogicalInfoActive())
ereport(FATAL,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("logical replication slot \"%s\" exists, but \"wal_level\" <
\"logical\"",
NameStr(cp.slotdata.name)),
- errhint("Change \"wal_level\" to be \"logical\" or higher.")));
+ errhint("Change \"wal_level\" to be \"logical\" or higher, or
activate logical decoding with \"replica\".")));

Another message that could be made more consistent with the similar
ones from CreatePublication, ValidateSlotSyncParams, etc...

e.g.
errmsg("logical replication slot \"%s\" exists, but logical decoding
is not enabled");
errhint("Set \"wal_level\" to \"logical\" or use
pg_activate_logical_decoding.");

======
src/backend/utils/activity/wait_event_names.txt

50.
+LOGICAL_DECODING_ACTIVATION "Waiting for logical decoding to be activated."

Should this be more like "Waiting for a requested logical decoding
activation to complete."

======
src/include/access/xlog.h

51.
-#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL)
+#define XLogLogicalInfoActive() (XLogLogicalInfoEnabled())

Those extra parentheses seem redundant now.

======
src/include/replication/logicalxlog.h

52.
+/*-------------------------------------------------------------------------
+ * logicalxlog.h
+ * Exports from replication/logical/logicalxlog.c.
+ *
+ * Copyright (c) 2012-2024, PostgreSQL Global Development Group
+ *
+ *-------------------------------------------------------------------------

/2024/2025/

~~~

53.
+typedef enum LogicalDecodingStatus
+{
+ LOGICAL_DECODING_STATUS_DISABLED = 0,
+ LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO,
+ LOGICAL_DECODING_STATUS_READY,
+} LogicalDecodingStatus;

Maybe some more comments about these status phases would be helpful.
Specifically, it's not immediately clear if the
LOGICAL_DECODING_STATUS_XLOG_LOGICALINFO is a real state we could find
ourselves permanently, or if it is more like just a temporary
"pending" state while transitioning from DISABLED to READY.

AFAICT it is just transitory, so in that case, maybe
LOGICAL_DECODING_PENDING might be a more appropriate name.

~~~

54.
+typedef struct XLogLogicalInfoCtlData XLogLogicalInfoCtlData;
+extern XLogLogicalInfoCtlData *XLogLogicalInfoCtl;
+extern bool XLogLogicalInfo;

Add a blank line between the typedef and the externs.

======
[1] Bertrand's hide everything idea -
https://www.postgresql.org/message-id/Z3fimYj0fbkLmWJb%40ip-10-97-1-34.eu-west-3.compute.internal

Kind Regards,
Peter Smith.
Fujitsu Australia


From: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-09 11:29:22
Message-ID: CAExHW5tyJrdjqKFQ+qDs8Yq3E_P1Fj_T4pwVW9WACmMznRtDuw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Dec 31, 2024 at 10:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Hi all,
>
> Logical decoding (and logical replication) are available only when
> wal_level = logical. As the documentation says[1], Using the 'logical'
> level increases the WAL volume which could negatively affect the
> performance. For that reason, users might want to start with using
> 'replica', but when they want to use logical decoding they need a
> server restart to increase wal_level to 'logical'. My goal is to allow
> users who are using 'replica' level to use logical decoding without a
> server restart. There are other GUC parameters related to logical
> decoding and logical replication such as max_wal_senders,
> max_logical_replication_workers, and max_replication_slots, but even
> if users set these parameters >0, there would not be a noticeable
> performance impact. And their default values are already >0. So I'd
> like to focus on making only the wal_level dynamic GUC parameter.
> There are several earlier discussions[2][3] but no one has submitted
> patches unless I'm missing something.
>
> The first idea I came up with is to make the wal_level a PGC_SIGHUP
> parameter. However, it affects not only setting 'replica' to 'logical'
> but also setting 'minimal' to 'replica' or higher. I'm not sure the
> latter case is common and it might require a checkpoint. I don't want
> to make the patch complex for uncommon cases.
>
> The second idea is to somehow allow both WAL-logging logical info and
> logical decoding even when wal_level is 'replica'. I've attached a PoC
> patch for that. The patch introduces new SQL functions such as
> pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> These functions are available only when wal_level is 'repilca'(or
> higher). In pg_activate_logical_decoding(), we set the status of
> logical decoding stored on the shared memory from 'disabled' to
> 'xlog-logical-info', allowing all processes to write logical
> information to WAL records for logical decoding. But the logical
> decoding is still not allowed. Once we confirm all in-progress
> transactions completed, we switch the status to
> 'logical-decoding-ready', meaning that users can create logical
> replication slots and use logical decoding.
>
> Overall, with the patch, there are two ways to enable logical
> decoding: setting wal_level to 'logical' and calling
> pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> 'logical' level for backward compatibility and for users who want to
> enable the logical decoding without calling that SQL function. If we
> can automatically enable the logical decoding when creating the first
> logical replication slot, probably we no longer need the 'logical'
> level. There is room to discuss the user interface. Feedback is very
> welcome.
>

If a server is running at minimal wal_level and they want to enable
logical replication, they would still need a server restart. That
would be rare but not completely absent.

Our documentation says "wal_level determines how much information is
written to the WAL.". Users would may not expect that the WAL amount
changes while wal_level = replica depending upon whether logical
decoding is possible. It may be possible to set the expectations right
by changing the documentation. It's not in the patch, so I am not sure
whether this is considered.

Cloud providers do not like multiple ways of changing configuration
esp. when they can not control it. See [1]. Changing wal_level through
a SQL function may fit the same category.

I agree that it would be a lot of work to make all combinations of
wal_level changes work, but changing wal_level through SIGHUP looks
like a cleaner solution. Is there way that we make the GUC SIGHUP but
disallow certain combinations of old and new values?

[1] https://www.postgresql.org/message-id/flat/CA%2BVUV5rEKt2%2BCdC_KUaPoihMu%2Bi5ChT4WVNTr4CD5-xXZUfuQw%40mail.gmail.com

--
Best Wishes,
Ashutosh Bapat


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-10 08:33:57
Message-ID: CAD21AoAuxr22MEqdt2YHbE9PaiPgc3=3f_1oXEeLnXXkO3uiYw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jan 9, 2025 at 3:29 AM Ashutosh Bapat
<ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
>
> On Tue, Dec 31, 2024 at 10:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > Hi all,
> >
> > Logical decoding (and logical replication) are available only when
> > wal_level = logical. As the documentation says[1], Using the 'logical'
> > level increases the WAL volume which could negatively affect the
> > performance. For that reason, users might want to start with using
> > 'replica', but when they want to use logical decoding they need a
> > server restart to increase wal_level to 'logical'. My goal is to allow
> > users who are using 'replica' level to use logical decoding without a
> > server restart. There are other GUC parameters related to logical
> > decoding and logical replication such as max_wal_senders,
> > max_logical_replication_workers, and max_replication_slots, but even
> > if users set these parameters >0, there would not be a noticeable
> > performance impact. And their default values are already >0. So I'd
> > like to focus on making only the wal_level dynamic GUC parameter.
> > There are several earlier discussions[2][3] but no one has submitted
> > patches unless I'm missing something.
> >
> > The first idea I came up with is to make the wal_level a PGC_SIGHUP
> > parameter. However, it affects not only setting 'replica' to 'logical'
> > but also setting 'minimal' to 'replica' or higher. I'm not sure the
> > latter case is common and it might require a checkpoint. I don't want
> > to make the patch complex for uncommon cases.
> >
> > The second idea is to somehow allow both WAL-logging logical info and
> > logical decoding even when wal_level is 'replica'. I've attached a PoC
> > patch for that. The patch introduces new SQL functions such as
> > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > These functions are available only when wal_level is 'repilca'(or
> > higher). In pg_activate_logical_decoding(), we set the status of
> > logical decoding stored on the shared memory from 'disabled' to
> > 'xlog-logical-info', allowing all processes to write logical
> > information to WAL records for logical decoding. But the logical
> > decoding is still not allowed. Once we confirm all in-progress
> > transactions completed, we switch the status to
> > 'logical-decoding-ready', meaning that users can create logical
> > replication slots and use logical decoding.
> >
> > Overall, with the patch, there are two ways to enable logical
> > decoding: setting wal_level to 'logical' and calling
> > pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> > 'logical' level for backward compatibility and for users who want to
> > enable the logical decoding without calling that SQL function. If we
> > can automatically enable the logical decoding when creating the first
> > logical replication slot, probably we no longer need the 'logical'
> > level. There is room to discuss the user interface. Feedback is very
> > welcome.
> >
>
> If a server is running at minimal wal_level and they want to enable
> logical replication, they would still need a server restart. That
> would be rare but not completely absent.

Currently we don't allow the server to start with the 'minimal' level
and max_wal_senders > 0. Even if we support changing 'minimal' to
'logical' without a server restart, we still need a server restart to
increase max_wal_senders for users who want to use logical
replication. Or we need to eliminate this restriction too. I guess it
would be too complex for such uncommon use cases.

>
> Our documentation says "wal_level determines how much information is
> written to the WAL.". Users would may not expect that the WAL amount
> changes while wal_level = replica depending upon whether logical
> decoding is possible. It may be possible to set the expectations right
> by changing the documentation. It's not in the patch, so I am not sure
> whether this is considered.

We should mention that in the doc. The WAL amount changes depending on
not only wal_level but also other parameters such as wal_log_hints and
full_page_writes.

> Cloud providers do not like multiple ways of changing configuration
> esp. when they can not control it. See [1]. Changing wal_level through
> a SQL function may fit the same category.

Thank you for pointing it out. This would support the idea of
automatically enabling logical decoding.

> I agree that it would be a lot of work to make all combinations of
> wal_level changes work, but changing wal_level through SIGHUP looks
> like a cleaner solution. Is there way that we make the GUC SIGHUP but
> disallow certain combinations of old and new values?

While I agree that it's cleaner I think there is no way today. I think
we need to invent something for that.

Another idea would be to have another SIGHUP GUC parameter to control
logical info as another way to enable logical info WAL-logging while
trying to deprecate the 'logical' level over some releases. While it
doesn't need a SQL function, it could confuse users since we will
require two GUC parameters for doing things that we used to use one
GUC parameter.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Peter Smith <smithpb2250(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-10 09:27:23
Message-ID: CAD21AoC07DV5LzppipBZmZfstKWhtx8rP470rssA6xQqtU6YUA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Tue, Jan 7, 2025 at 11:30 PM Peter Smith <smithpb2250(at)gmail(dot)com> wrote:
>
> Hi Sawada-San.
>
> FWIW, I also thought it was a good idea suggested by Bertrand [1] to
> "hide" everything behind the slot create/delete, and thereby eliminate
> the need for user intervention using those new
> pg_activate/deactivate_logical_decoding functions.
>
> But, one concern doing it this way is how to prevent a user
> (accidentally?) getting themselves into a different replication mode
> without realising it? Or say they change the mode and then "forget"
> that they did that.

I think that as long as there is at least one logical replication slot
users still have the will to execute logical decoding, so they require
logical info WAL-logging. I think it would rather be good for users to
be able to forget about that.

> For example, If wal_level=replica and then somebody does CREATE
> PUBLICATION/SUBSCRIPTION won't that implicitly enable the logical
> decoding and then leave it enabled until all the logical replication
> slots are eventually dropped?

Yes.

> Now, when the user examines wal_level it
> is still going to show 'replica', which could be misleading --- e.g.
> how will they even know that they can't really trust that anymore, and
> they must also check the pg_get_logical_decoding_status?

I think that if we automatically enable logical decoding even when
wal_level=replica, we would not need pg_get_logical_decoding_status().
These changes would break compatibility tools checking if wal_level is
'logical', but I guess that tools will not need to check that anymore.
Users can simply understand that if there is at least one logical
replication slot the system writes necessary information to use it.
Having said that we anyway need to mention it in the doc and raising
NOTICE/WARNING would also be a good idea as you mentioned.

>
> Meanwhile, although it is premature to give detailed code review
> comments for what is still a PoC, during my reading of your patch I
> made copious notes for myself, so I thought I might as well post what
> I have regardless. See the details below in this post. Ignore, or do
> with them as you wish. But, hopefully, a lot of the following feedback
> will still be relevant regardless of any design changes.

Thank you for reviewing the patch! It seems that most comments are
about wording, typos, suggestions for variable names and function
names etc. Since the patch is in the PoC/design phase where we might
need to change the whole design, I'll refer to these comments when
updating the patch next time.

Regards,

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


From: Peter Smith <smithpb2250(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-13 06:52:15
Message-ID: CAHut+Pt5kbvovumGu62iMOTNNPnm4PqoDr1nxMM4=HRVdeGnfQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jan 10, 2025 at 8:28 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Tue, Jan 7, 2025 at 11:30 PM Peter Smith <smithpb2250(at)gmail(dot)com> wrote:
> >
> > Hi Sawada-San.
> >
> > FWIW, I also thought it was a good idea suggested by Bertrand [1] to
> > "hide" everything behind the slot create/delete, and thereby eliminate
> > the need for user intervention using those new
> > pg_activate/deactivate_logical_decoding functions.
> >
> > But, one concern doing it this way is how to prevent a user
> > (accidentally?) getting themselves into a different replication mode
> > without realising it? Or say they change the mode and then "forget"
> > that they did that.
>
> I think that as long as there is at least one logical replication slot
> users still have the will to execute logical decoding, so they require
> logical info WAL-logging. I think it would rather be good for users to
> be able to forget about that.
>
> > For example, If wal_level=replica and then somebody does CREATE
> > PUBLICATION/SUBSCRIPTION won't that implicitly enable the logical
> > decoding and then leave it enabled until all the logical replication
> > slots are eventually dropped?
>
> Yes.
>
> > Now, when the user examines wal_level it
> > is still going to show 'replica', which could be misleading --- e.g.
> > how will they even know that they can't really trust that anymore, and
> > they must also check the pg_get_logical_decoding_status?
>
> I think that if we automatically enable logical decoding even when
> wal_level=replica, we would not need pg_get_logical_decoding_status().
> These changes would break compatibility tools checking if wal_level is
> 'logical', but I guess that tools will not need to check that anymore.
> Users can simply understand that if there is at least one logical
> replication slot the system writes necessary information to use it.
> Having said that we anyway need to mention it in the doc and raising
> NOTICE/WARNING would also be a good idea as you mentioned.
>

Hi Sawada-San

IMO it seems misleading to be having logical replication behaviour
while the wal_level still displays as 'replica'.

So, I was wondering if it would be worthwhile to introduce a
'show_hook' for this GUC.

I hacked a quick implementation (attached) which now displays a middle
value for this scenario as "replica-logical". See below:

test_pub=# show wal_level;
wal_level
-----------
replica
(1 row)

test_pub=# select pg_get_logical_decoding_status();
pg_get_logical_decoding_status
--------------------------------
disabled
(1 row)

test_pub=# select pg_activate_logical_decoding();
pg_activate_logical_decoding
------------------------------

(1 row)

test_pub=# show wal_level;
wal_level
-----------------
replica-logical
(1 row)

test_pub=# select pg_get_logical_decoding_status();
pg_get_logical_decoding_status
--------------------------------
ready

(1 row)
test_pub=# \x
Expanded display is on.
test_pub=# select * from pg_settings where name in ('wal_level');
-[ RECORD 1 ]---+--------------------------------------------------
name | wal_level
setting | replica-logical
unit |
category | Write-Ahead Log / Settings
short_desc | Sets the level of information written to the WAL.
extra_desc |
context | postmaster
vartype | enum
source | configuration file
min_val |
max_val |
enumvals | {minimal,replica,logical}
boot_val | replica
reset_val | replica
sourcefile | /home/postgres/MYDATAOSS_2PC_PUB/postgresql.conf
sourceline | 199
pending_restart | f

~~

OTOH, you might prefer to display the "replica-logical" case as
"logical". (doing so might make things easier for existing tools that
are already checking if wal_level is "logical").

Of course, it doesn't really change the 'wal_level' variable value, it
just changes how it is *displayed*. Anyway, maybe it's an idea to
consider.

======
Kind Regards,
Peter Smith.
Fujitsu Australia

Attachment Content-Type Size
PS_guc_show_hook.txt text/plain 1.8 KB

From: vignesh C <vignesh21(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-13 09:22:31
Message-ID: CALDaNm3QJoGE9tojsFbMYduwAEtdp-NfQTnqp9daOr-c24hibg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, 31 Dec 2024 at 10:15, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Hi all,
>
> Logical decoding (and logical replication) are available only when
> wal_level = logical. As the documentation says[1], Using the 'logical'
> level increases the WAL volume which could negatively affect the
> performance. For that reason, users might want to start with using
> 'replica', but when they want to use logical decoding they need a
> server restart to increase wal_level to 'logical'. My goal is to allow
> users who are using 'replica' level to use logical decoding without a
> server restart. There are other GUC parameters related to logical
> decoding and logical replication such as max_wal_senders,
> max_logical_replication_workers, and max_replication_slots, but even
> if users set these parameters >0, there would not be a noticeable
> performance impact. And their default values are already >0. So I'd
> like to focus on making only the wal_level dynamic GUC parameter.
> There are several earlier discussions[2][3] but no one has submitted
> patches unless I'm missing something.
>
> The first idea I came up with is to make the wal_level a PGC_SIGHUP
> parameter. However, it affects not only setting 'replica' to 'logical'
> but also setting 'minimal' to 'replica' or higher. I'm not sure the
> latter case is common and it might require a checkpoint. I don't want
> to make the patch complex for uncommon cases.
>
> The second idea is to somehow allow both WAL-logging logical info and
> logical decoding even when wal_level is 'replica'. I've attached a PoC
> patch for that. The patch introduces new SQL functions such as
> pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> These functions are available only when wal_level is 'repilca'(or
> higher). In pg_activate_logical_decoding(), we set the status of
> logical decoding stored on the shared memory from 'disabled' to
> 'xlog-logical-info', allowing all processes to write logical
> information to WAL records for logical decoding. But the logical
> decoding is still not allowed. Once we confirm all in-progress
> transactions completed, we switch the status to
> 'logical-decoding-ready', meaning that users can create logical
> replication slots and use logical decoding.

I felt that the only disadvantage with this approach is that we
currently wait for all in-progress transactions to complete before
enabling logical decoding. If a long-running transaction exists and
the session enabling logical decoding fails—due to factors like
statement_timeout, transaction_timeout,
idle_in_transaction_session_timeout, idle_session_timeout, or any
other failure. This would require restarting the wait. During this
time, there's a risk that a new long-running transaction could start,
further delaying the process. Probably this could be solved if the
waiting is done from any of the background processes through
PGC_SIGHUP. While this type of failure is likely rare, I’m unsure
whether we should consider this scenario.

Thoughts?

Regards,
Vignesh


From: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
To: vignesh C <vignesh21(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-13 09:31:29
Message-ID: CAExHW5s76aTZmgHYY+w8XfwKdYzUUEDQegYScEWW2d7nN3Nw+g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jan 13, 2025 at 2:52 PM vignesh C <vignesh21(at)gmail(dot)com> wrote:
>
> I felt that the only disadvantage with this approach is that we
> currently wait for all in-progress transactions to complete before
> enabling logical decoding. If a long-running transaction exists and
> the session enabling logical decoding fails—due to factors like
> statement_timeout, transaction_timeout,
> idle_in_transaction_session_timeout, idle_session_timeout, or any
> other failure. This would require restarting the wait. During this
> time, there's a risk that a new long-running transaction could start,
> further delaying the process. Probably this could be solved if the
> waiting is done from any of the background processes through
> PGC_SIGHUP. While this type of failure is likely rare, I’m unsure
> whether we should consider this scenario.

A related question: While the operation is waiting for already running
transactions to end, the backends whose transactions have finished may
start new transactions. When we switch WAL from 'replica' to
'logical', there may be some transactions running. Will this lead to
WAL stream with mixes WAL records - some with logical information and
some without? Do we need to adjust logical decoding to tackle this
situation? Is there a chance that some WAL from same transaction have
logical information and some do not?

--
Best Wishes,
Ashutosh Bapat


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: vignesh C <vignesh21(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-13 21:32:42
Message-ID: CAD21AoC+vt7qTne7QLd=kM4gX+dV3zpvY_hZNhVAaf82p4knOA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jan 13, 2025 at 1:22 AM vignesh C <vignesh21(at)gmail(dot)com> wrote:
>
> On Tue, 31 Dec 2024 at 10:15, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > Hi all,
> >
> > Logical decoding (and logical replication) are available only when
> > wal_level = logical. As the documentation says[1], Using the 'logical'
> > level increases the WAL volume which could negatively affect the
> > performance. For that reason, users might want to start with using
> > 'replica', but when they want to use logical decoding they need a
> > server restart to increase wal_level to 'logical'. My goal is to allow
> > users who are using 'replica' level to use logical decoding without a
> > server restart. There are other GUC parameters related to logical
> > decoding and logical replication such as max_wal_senders,
> > max_logical_replication_workers, and max_replication_slots, but even
> > if users set these parameters >0, there would not be a noticeable
> > performance impact. And their default values are already >0. So I'd
> > like to focus on making only the wal_level dynamic GUC parameter.
> > There are several earlier discussions[2][3] but no one has submitted
> > patches unless I'm missing something.
> >
> > The first idea I came up with is to make the wal_level a PGC_SIGHUP
> > parameter. However, it affects not only setting 'replica' to 'logical'
> > but also setting 'minimal' to 'replica' or higher. I'm not sure the
> > latter case is common and it might require a checkpoint. I don't want
> > to make the patch complex for uncommon cases.
> >
> > The second idea is to somehow allow both WAL-logging logical info and
> > logical decoding even when wal_level is 'replica'. I've attached a PoC
> > patch for that. The patch introduces new SQL functions such as
> > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > These functions are available only when wal_level is 'repilca'(or
> > higher). In pg_activate_logical_decoding(), we set the status of
> > logical decoding stored on the shared memory from 'disabled' to
> > 'xlog-logical-info', allowing all processes to write logical
> > information to WAL records for logical decoding. But the logical
> > decoding is still not allowed. Once we confirm all in-progress
> > transactions completed, we switch the status to
> > 'logical-decoding-ready', meaning that users can create logical
> > replication slots and use logical decoding.
>
> I felt that the only disadvantage with this approach is that we
> currently wait for all in-progress transactions to complete before
> enabling logical decoding. If a long-running transaction exists and
> the session enabling logical decoding fails—due to factors like
> statement_timeout, transaction_timeout,
> idle_in_transaction_session_timeout, idle_session_timeout, or any
> other failure. This would require restarting the wait. During this
> time, there's a risk that a new long-running transaction could start,
> further delaying the process. Probably this could be solved if the
> waiting is done from any of the background processes through
> PGC_SIGHUP. While this type of failure is likely rare, I’m unsure
> whether we should consider this scenario.
>
> Thoughts?

Yeah, delegating the activation to the background process such as the
checkpointer would also be one solution. This would work with the
approach that we enable the logical decoding via
pg_activate_logical_decoding(). On the other hand, if we support
automatically enabling the logical decoding (and logical info logging)
when the first logical slot is created, we might want to have the
process who is creating the logical slot activate the logical decoding
too.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: vignesh C <vignesh21(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-13 21:45:15
Message-ID: CAD21AoBWvdA5SU2fFaUXsGqC=_NHqM+o2eDHAW01WaGVHYDOuQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jan 13, 2025 at 1:31 AM Ashutosh Bapat
<ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
>
> On Mon, Jan 13, 2025 at 2:52 PM vignesh C <vignesh21(at)gmail(dot)com> wrote:
> >
> > I felt that the only disadvantage with this approach is that we
> > currently wait for all in-progress transactions to complete before
> > enabling logical decoding. If a long-running transaction exists and
> > the session enabling logical decoding fails—due to factors like
> > statement_timeout, transaction_timeout,
> > idle_in_transaction_session_timeout, idle_session_timeout, or any
> > other failure. This would require restarting the wait. During this
> > time, there's a risk that a new long-running transaction could start,
> > further delaying the process. Probably this could be solved if the
> > waiting is done from any of the background processes through
> > PGC_SIGHUP. While this type of failure is likely rare, I’m unsure
> > whether we should consider this scenario.
>
> A related question: While the operation is waiting for already running
> transactions to end, the backends whose transactions have finished may
> start new transactions. When we switch WAL from 'replica' to
> 'logical', there may be some transactions running. Will this lead to
> WAL stream with mixes WAL records - some with logical information and
> some without?

Yes. There could be mixed WAL records until all running transactions complete.

> Do we need to adjust logical decoding to tackle this
> situation? Is there a chance that some WAL from same transaction have
> logical information and some do not?

In the current approach, we first enable logical info WAL-logging to
let newly started transactions do logical info WAL-logging, then allow
the logical decoding only after all running transactions complete.
Therefore, at the time when we allow the logical decoding, all WAL
records are written with logical information.

Regards,

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


From: vignesh C <vignesh21(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-15 04:34:50
Message-ID: CALDaNm1fWiwQcopeFuL4gfX8VRGWW5axm52j9T=A-RreikTBew@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, 14 Jan 2025 at 03:03, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Yeah, delegating the activation to the background process such as the
> checkpointer would also be one solution. This would work with the
> approach that we enable the logical decoding via
> pg_activate_logical_decoding(). On the other hand, if we support
> automatically enabling the logical decoding (and logical info logging)
> when the first logical slot is created, we might want to have the
> process who is creating the logical slot activate the logical decoding
> too.

One possible approach is to delegate the task of updating the wal
level to include logical decoding information during the creation of
the first logical replication slot also to a background process (e.g.,
the checkpoint process) and wait until the wal level has been updated
and reaches ready state. Additionally, we could introduce a new
optional parameter during slot creation to specify whether we should
roll back changes related to updating the WAL level in case of
failure. If a rollback is needed, we could invoke the
logical_decoding_activation_abort_callback. By default, the rollback
could be set to false, since in most failure scenarios, the user will
likely attempt to create the slot again immediately. By then, the WAL
level may have already been updated, eliminating the need to wait for
any new long-running transactions.
An alternative approach could be to skip the rollback of logical info
logging during logical replication slot creation in case of failure,
without introducing a rollback parameter. This is because there may be
concurrent transactions (e.g., parallel slot creation or
pg_activate_logical_decoding from different sessions) that would also
fail. In such cases, the user could be allowed to call
pg_deactivate_logical_decoding if needed.

Regards,
Vignesh


From: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: vignesh C <vignesh21(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-15 05:46:02
Message-ID: CAExHW5tNYixOoVHwENGxiRWnGtsff17V4F9aQap7a5AGawC+MQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jan 14, 2025 at 3:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Mon, Jan 13, 2025 at 1:31 AM Ashutosh Bapat
> <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> >
> > On Mon, Jan 13, 2025 at 2:52 PM vignesh C <vignesh21(at)gmail(dot)com> wrote:
> > >
> > > I felt that the only disadvantage with this approach is that we
> > > currently wait for all in-progress transactions to complete before
> > > enabling logical decoding. If a long-running transaction exists and
> > > the session enabling logical decoding fails—due to factors like
> > > statement_timeout, transaction_timeout,
> > > idle_in_transaction_session_timeout, idle_session_timeout, or any
> > > other failure. This would require restarting the wait. During this
> > > time, there's a risk that a new long-running transaction could start,
> > > further delaying the process. Probably this could be solved if the
> > > waiting is done from any of the background processes through
> > > PGC_SIGHUP. While this type of failure is likely rare, I’m unsure
> > > whether we should consider this scenario.
> >
> > A related question: While the operation is waiting for already running
> > transactions to end, the backends whose transactions have finished may
> > start new transactions. When we switch WAL from 'replica' to
> > 'logical', there may be some transactions running. Will this lead to
> > WAL stream with mixes WAL records - some with logical information and
> > some without?
>
> Yes. There could be mixed WAL records until all running transactions complete.
>
> > Do we need to adjust logical decoding to tackle this
> > situation? Is there a chance that some WAL from same transaction have
> > logical information and some do not?
>
> In the current approach, we first enable logical info WAL-logging to
> let newly started transactions do logical info WAL-logging, then allow
> the logical decoding only after all running transactions complete.
> Therefore, at the time when we allow the logical decoding, all WAL
> records are written with logical information.

Thanks for the clarification. Let's consider that T1, T2, T3 were
running when the request to enable logical decoding came in. Let's say
T1 finished first, then T2 and then T3. But in-the mean time T4, T5
and T6 were started, which logged WAL with logical information. While
T2, T3, T4, T5, T6 all are running simultaneously, there will be mixed
WAL logs (some with logical information and some without). When T3
ends, logical decoding will be allowed. If a logical decoding process
is started at this point, it will start reading WAL from the earliest
of T4, T5 or T6 and hence it will encounter WAL written by T2 or T3
which do not have logical information. That would create a problem.
Thus in order for the logical process to start The transactions T4, T5
and T6 need to be finished as well. Am I correct? If that is so, my
earlier proposal to combine the step to wait for running transactions
to complete for both logical decoding as well as replication slot
creation would not be possible.

Will the mixed logs create a problem for an ongoing physical stream replication?

--
Best Wishes,
Ashutosh Bapat


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Peter Smith <smithpb2250(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-15 17:27:54
Message-ID: CAD21AoDghp6VJPU68VHnCnVPY-BrUn68H5rXXNv9Z+1oDmJtow@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, Jan 12, 2025 at 10:52 PM Peter Smith <smithpb2250(at)gmail(dot)com> wrote:
>
> On Fri, Jan 10, 2025 at 8:28 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > Hi,
> >
> > On Tue, Jan 7, 2025 at 11:30 PM Peter Smith <smithpb2250(at)gmail(dot)com> wrote:
> > >
> > > Hi Sawada-San.
> > >
> > > FWIW, I also thought it was a good idea suggested by Bertrand [1] to
> > > "hide" everything behind the slot create/delete, and thereby eliminate
> > > the need for user intervention using those new
> > > pg_activate/deactivate_logical_decoding functions.
> > >
> > > But, one concern doing it this way is how to prevent a user
> > > (accidentally?) getting themselves into a different replication mode
> > > without realising it? Or say they change the mode and then "forget"
> > > that they did that.
> >
> > I think that as long as there is at least one logical replication slot
> > users still have the will to execute logical decoding, so they require
> > logical info WAL-logging. I think it would rather be good for users to
> > be able to forget about that.
> >
> > > For example, If wal_level=replica and then somebody does CREATE
> > > PUBLICATION/SUBSCRIPTION won't that implicitly enable the logical
> > > decoding and then leave it enabled until all the logical replication
> > > slots are eventually dropped?
> >
> > Yes.
> >
> > > Now, when the user examines wal_level it
> > > is still going to show 'replica', which could be misleading --- e.g.
> > > how will they even know that they can't really trust that anymore, and
> > > they must also check the pg_get_logical_decoding_status?
> >
> > I think that if we automatically enable logical decoding even when
> > wal_level=replica, we would not need pg_get_logical_decoding_status().
> > These changes would break compatibility tools checking if wal_level is
> > 'logical', but I guess that tools will not need to check that anymore.
> > Users can simply understand that if there is at least one logical
> > replication slot the system writes necessary information to use it.
> > Having said that we anyway need to mention it in the doc and raising
> > NOTICE/WARNING would also be a good idea as you mentioned.
> >
>
> Hi Sawada-San
>
> IMO it seems misleading to be having logical replication behaviour
> while the wal_level still displays as 'replica'.
>
> So, I was wondering if it would be worthwhile to introduce a
> 'show_hook' for this GUC.
>
> I hacked a quick implementation (attached) which now displays a middle
> value for this scenario as "replica-logical". See below:
>
> test_pub=# show wal_level;
> wal_level
> -----------
> replica
> (1 row)
>
> test_pub=# select pg_get_logical_decoding_status();
> pg_get_logical_decoding_status
> --------------------------------
> disabled
> (1 row)
>
> test_pub=# select pg_activate_logical_decoding();
> pg_activate_logical_decoding
> ------------------------------
>
> (1 row)
>
> test_pub=# show wal_level;
> wal_level
> -----------------
> replica-logical
> (1 row)

I think this would break the compatibility for monitoring tools
anyway. Given that the logical decoding is enabled if there is at
least one logical slot, they just need to check the number of existing
logical slots to know whether logical info WAL-logging is enabled or
not.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: vignesh C <vignesh21(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-15 17:55:51
Message-ID: CAD21AoBWaLYdDJ4J8=dYMFgkt7ncattB51bBTSTw1v+mr1kF0w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jan 14, 2025 at 9:46 PM Ashutosh Bapat
<ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
>
> On Tue, Jan 14, 2025 at 3:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Mon, Jan 13, 2025 at 1:31 AM Ashutosh Bapat
> > <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> > >
> > > On Mon, Jan 13, 2025 at 2:52 PM vignesh C <vignesh21(at)gmail(dot)com> wrote:
> > > >
> > > > I felt that the only disadvantage with this approach is that we
> > > > currently wait for all in-progress transactions to complete before
> > > > enabling logical decoding. If a long-running transaction exists and
> > > > the session enabling logical decoding fails—due to factors like
> > > > statement_timeout, transaction_timeout,
> > > > idle_in_transaction_session_timeout, idle_session_timeout, or any
> > > > other failure. This would require restarting the wait. During this
> > > > time, there's a risk that a new long-running transaction could start,
> > > > further delaying the process. Probably this could be solved if the
> > > > waiting is done from any of the background processes through
> > > > PGC_SIGHUP. While this type of failure is likely rare, I’m unsure
> > > > whether we should consider this scenario.
> > >
> > > A related question: While the operation is waiting for already running
> > > transactions to end, the backends whose transactions have finished may
> > > start new transactions. When we switch WAL from 'replica' to
> > > 'logical', there may be some transactions running. Will this lead to
> > > WAL stream with mixes WAL records - some with logical information and
> > > some without?
> >
> > Yes. There could be mixed WAL records until all running transactions complete.
> >
> > > Do we need to adjust logical decoding to tackle this
> > > situation? Is there a chance that some WAL from same transaction have
> > > logical information and some do not?
> >
> > In the current approach, we first enable logical info WAL-logging to
> > let newly started transactions do logical info WAL-logging, then allow
> > the logical decoding only after all running transactions complete.
> > Therefore, at the time when we allow the logical decoding, all WAL
> > records are written with logical information.
>
> Thanks for the clarification. Let's consider that T1, T2, T3 were
> running when the request to enable logical decoding came in. Let's say
> T1 finished first, then T2 and then T3. But in-the mean time T4, T5
> and T6 were started, which logged WAL with logical information. While
> T2, T3, T4, T5, T6 all are running simultaneously, there will be mixed
> WAL logs (some with logical information and some without). When T3
> ends, logical decoding will be allowed. If a logical decoding process
> is started at this point, it will start reading WAL from the earliest
> of T4, T5 or T6 and hence it will encounter WAL written by T2 or T3
> which do not have logical information.

IIUC we should prevent a logical slot from reserving the WAL until T1,
T2, and T3 finishes. That is, we wait for T1, T2, and T3 to finish
before calling ReplicationSlotReserveWal() where we decide the start
point for reading WAL. That way, the logical decoding will start
reading WAL from the point after the latest commit record of T1, T2,
and T3 (i.e. T3 in this case), meaning that there is no mixed WAL
after this point and T4, T5, and T6 would not be included in the
logical decoding.

> Will the mixed logs create a problem for an ongoing physical stream replication?

I don't see any problem for physical stream replication in terms of
mixed logs. We write a WAL record to enable the logical decoding after
the point where we can ensure there are no mixed WAL records. So the
logical decoding on standbys also can start reading WAL records from
that point.

Regards,

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


From: Peter Smith <smithpb2250(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-16 01:44:56
Message-ID: CAHut+Pvrnw+=i1K0WpwfH=nHTsvyk2ZYBg6yAEo1Z=Um7CARTQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jan 16, 2025 at 4:28 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Sun, Jan 12, 2025 at 10:52 PM Peter Smith <smithpb2250(at)gmail(dot)com> wrote:
> >
> > On Fri, Jan 10, 2025 at 8:28 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Jan 7, 2025 at 11:30 PM Peter Smith <smithpb2250(at)gmail(dot)com> wrote:
> > > >
> > > > Hi Sawada-San.
> > > >
> > > > FWIW, I also thought it was a good idea suggested by Bertrand [1] to
> > > > "hide" everything behind the slot create/delete, and thereby eliminate
> > > > the need for user intervention using those new
> > > > pg_activate/deactivate_logical_decoding functions.
> > > >
> > > > But, one concern doing it this way is how to prevent a user
> > > > (accidentally?) getting themselves into a different replication mode
> > > > without realising it? Or say they change the mode and then "forget"
> > > > that they did that.
> > >
> > > I think that as long as there is at least one logical replication slot
> > > users still have the will to execute logical decoding, so they require
> > > logical info WAL-logging. I think it would rather be good for users to
> > > be able to forget about that.
> > >
> > > > For example, If wal_level=replica and then somebody does CREATE
> > > > PUBLICATION/SUBSCRIPTION won't that implicitly enable the logical
> > > > decoding and then leave it enabled until all the logical replication
> > > > slots are eventually dropped?
> > >
> > > Yes.
> > >
> > > > Now, when the user examines wal_level it
> > > > is still going to show 'replica', which could be misleading --- e.g.
> > > > how will they even know that they can't really trust that anymore, and
> > > > they must also check the pg_get_logical_decoding_status?
> > >
> > > I think that if we automatically enable logical decoding even when
> > > wal_level=replica, we would not need pg_get_logical_decoding_status().
> > > These changes would break compatibility tools checking if wal_level is
> > > 'logical', but I guess that tools will not need to check that anymore.
> > > Users can simply understand that if there is at least one logical
> > > replication slot the system writes necessary information to use it.
> > > Having said that we anyway need to mention it in the doc and raising
> > > NOTICE/WARNING would also be a good idea as you mentioned.
> > >
> >
> > Hi Sawada-San
> >
> > IMO it seems misleading to be having logical replication behaviour
> > while the wal_level still displays as 'replica'.
> >
> > So, I was wondering if it would be worthwhile to introduce a
> > 'show_hook' for this GUC.
> >
> > I hacked a quick implementation (attached) which now displays a middle
> > value for this scenario as "replica-logical". See below:
> >
> > test_pub=# show wal_level;
> > wal_level
> > -----------
> > replica
> > (1 row)
> >
> > test_pub=# select pg_get_logical_decoding_status();
> > pg_get_logical_decoding_status
> > --------------------------------
> > disabled
> > (1 row)
> >
> > test_pub=# select pg_activate_logical_decoding();
> > pg_activate_logical_decoding
> > ------------------------------
> >
> > (1 row)
> >
> > test_pub=# show wal_level;
> > wal_level
> > -----------------
> > replica-logical
> > (1 row)
>
> I think this would break the compatibility for monitoring tools
> anyway. Given that the logical decoding is enabled if there is at
> least one logical slot, they just need to check the number of existing
> logical slots to know whether logical info WAL-logging is enabled or
> not.
>

But, that "replica-logical" string value was just for my demonstration.

From your reply, I cannot tell if you accidentally overlooked the next
part where I said:
OTOH, you might prefer to display the "replica-logical" case as "logical".

~~~

e.g. then the above example would look like this:

test_pub=# show wal_level;
wal_level
-----------
replica
(1 row)

test_pub=# select pg_get_logical_decoding_status();
pg_get_logical_decoding_status
--------------------------------
disabled
(1 row)

test_pub=# select pg_activate_logical_decoding();
pg_activate_logical_decoding
------------------------------
(1 row)

test_pub=# show wal_level;
wal_level
-----------
logical
(1 row)

Eventually, if the number of logical replication slots falls to 0, the
wal_level value displayed reverts to "replica".

Since there are no *new* wal_level strings introduced how would that
break compatibility for monitoring tools?

And, since the (fudged) wal_level value "logical" already indicates
whether logical info WAL-logging is enabled or not, no additional
kinds of checking are needed.

======
Kind Regards,
Peter Smith.
Fujitsu Australia


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, Euler Taveira <euler(at)eulerto(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-22 10:04:11
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Mon, Jan 06, 2025 at 10:32:52PM -0800, Masahiko Sawada wrote:
> On Mon, Jan 6, 2025 at 3:20 AM Ashutosh Bapat
> <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> >
> > On Sat, Jan 4, 2025 at 6:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Fri, Jan 3, 2025 at 6:31 AM Euler Taveira <euler(at)eulerto(dot)com> wrote:
> > > >
> > > > On Fri, Jan 3, 2025, at 10:14 AM, Bertrand Drouvot wrote:
> > > >
> > > > If we don't want to force wal_level = logical to enable logical decoding (your
> > > > second idea) then I think that it would be better to "hide" everything behind
> > > > logical replication slot creation / deletion. That would mean that having at
> > > > least one logical replication slot created would be synonym to "activate logical
> > > > decoding" and zero logical replication slot created would be synonym to "deactivate
> > > > logical decoding".
> > > >
> > > >
> > > > I like this idea. The logical replication slot existence already has the
> > > > required protections and guarantees (no running transactions from the past while
> > > > creating) for logical decoding.
> > >
> > > I agree that it's better behavior.
> > >
> > > >
> > > > Having said that, you are basically folding 'logical' machinery into 'replica'.
> > > > The 'logical' option can still exists but it will be less attractive because it
> > > > increases the WAL volume even if you are not using logical replication. I don't
> > > > know if the current 'logical' behavior (WAL records for logical decoding even
> > > > if there is no active logical replication) has any use case (maybe someone
> > > > inspects these extra records for analysis) but one suggestion (separate patch)
> > > > is to make 'logical' synonymous with the new 'replica' behavior (logical
> > > > decoding capability). This opens the door to remove 'logical' in future
> > > > releases (accepted as synonym but not documented).
>
> FYI one possible use case of the 'logical' level would be that if we
> support retrieving WAL records for logical decoding from somewhere
> like restore_command in the future, users would like to keep the
> wal_level 'logical' or keep the logical decoding active.

Another use case is to allow logical decoding from standby. One could set
wal_level to logical on the primary to be able to create a logical replication
slot on the standby (without having the need to create one on the primary).

BTW, currently it's mandatory to set wal_level to logical on the primary to
be able to create a logical replication slot on the standby. Should we extend
this to "logical decoding is enabled on the primary" too?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, Euler Taveira <euler(at)eulerto(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-22 21:17:03
Message-ID: CAD21AoCj9n9Trc7qoQjNvBxHXi4bQe==h5itzPkXuTeVk2ymRw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jan 22, 2025 at 2:04 AM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Mon, Jan 06, 2025 at 10:32:52PM -0800, Masahiko Sawada wrote:
> > On Mon, Jan 6, 2025 at 3:20 AM Ashutosh Bapat
> > <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> > >
> > > On Sat, Jan 4, 2025 at 6:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Fri, Jan 3, 2025 at 6:31 AM Euler Taveira <euler(at)eulerto(dot)com> wrote:
> > > > >
> > > > > On Fri, Jan 3, 2025, at 10:14 AM, Bertrand Drouvot wrote:
> > > > >
> > > > > If we don't want to force wal_level = logical to enable logical decoding (your
> > > > > second idea) then I think that it would be better to "hide" everything behind
> > > > > logical replication slot creation / deletion. That would mean that having at
> > > > > least one logical replication slot created would be synonym to "activate logical
> > > > > decoding" and zero logical replication slot created would be synonym to "deactivate
> > > > > logical decoding".
> > > > >
> > > > >
> > > > > I like this idea. The logical replication slot existence already has the
> > > > > required protections and guarantees (no running transactions from the past while
> > > > > creating) for logical decoding.
> > > >
> > > > I agree that it's better behavior.
> > > >
> > > > >
> > > > > Having said that, you are basically folding 'logical' machinery into 'replica'.
> > > > > The 'logical' option can still exists but it will be less attractive because it
> > > > > increases the WAL volume even if you are not using logical replication. I don't
> > > > > know if the current 'logical' behavior (WAL records for logical decoding even
> > > > > if there is no active logical replication) has any use case (maybe someone
> > > > > inspects these extra records for analysis) but one suggestion (separate patch)
> > > > > is to make 'logical' synonymous with the new 'replica' behavior (logical
> > > > > decoding capability). This opens the door to remove 'logical' in future
> > > > > releases (accepted as synonym but not documented).
> >
> > FYI one possible use case of the 'logical' level would be that if we
> > support retrieving WAL records for logical decoding from somewhere
> > like restore_command in the future, users would like to keep the
> > wal_level 'logical' or keep the logical decoding active.
>
> Another use case is to allow logical decoding from standby. One could set
> wal_level to logical on the primary to be able to create a logical replication
> slot on the standby (without having the need to create one on the primary).

Good point. It seems to be a substantial disadvantage for users.

>
> BTW, currently it's mandatory to set wal_level to logical on the primary to
> be able to create a logical replication slot on the standby. Should we extend
> this to "logical decoding is enabled on the primary" too?

Yes, in order to use the logical decoding on standbys, we need to
enable it on the primary. When enabling the logical decoding on the
primary we can write a WAL record so that standby servers can enable
the logical decoding too.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-23 00:46:00
Message-ID: CAD21AoAwM=Sg2haXrvyB+5RGaK0K7QFObRTie81NAF6khSCogQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jan 10, 2025 at 12:33 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Jan 9, 2025 at 3:29 AM Ashutosh Bapat
> <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> >
> > On Tue, Dec 31, 2024 at 10:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > Hi all,
> > >
> > > Logical decoding (and logical replication) are available only when
> > > wal_level = logical. As the documentation says[1], Using the 'logical'
> > > level increases the WAL volume which could negatively affect the
> > > performance. For that reason, users might want to start with using
> > > 'replica', but when they want to use logical decoding they need a
> > > server restart to increase wal_level to 'logical'. My goal is to allow
> > > users who are using 'replica' level to use logical decoding without a
> > > server restart. There are other GUC parameters related to logical
> > > decoding and logical replication such as max_wal_senders,
> > > max_logical_replication_workers, and max_replication_slots, but even
> > > if users set these parameters >0, there would not be a noticeable
> > > performance impact. And their default values are already >0. So I'd
> > > like to focus on making only the wal_level dynamic GUC parameter.
> > > There are several earlier discussions[2][3] but no one has submitted
> > > patches unless I'm missing something.
> > >
> > > The first idea I came up with is to make the wal_level a PGC_SIGHUP
> > > parameter. However, it affects not only setting 'replica' to 'logical'
> > > but also setting 'minimal' to 'replica' or higher. I'm not sure the
> > > latter case is common and it might require a checkpoint. I don't want
> > > to make the patch complex for uncommon cases.
> > >
> > > The second idea is to somehow allow both WAL-logging logical info and
> > > logical decoding even when wal_level is 'replica'. I've attached a PoC
> > > patch for that. The patch introduces new SQL functions such as
> > > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > > These functions are available only when wal_level is 'repilca'(or
> > > higher). In pg_activate_logical_decoding(), we set the status of
> > > logical decoding stored on the shared memory from 'disabled' to
> > > 'xlog-logical-info', allowing all processes to write logical
> > > information to WAL records for logical decoding. But the logical
> > > decoding is still not allowed. Once we confirm all in-progress
> > > transactions completed, we switch the status to
> > > 'logical-decoding-ready', meaning that users can create logical
> > > replication slots and use logical decoding.
> > >
> > > Overall, with the patch, there are two ways to enable logical
> > > decoding: setting wal_level to 'logical' and calling
> > > pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> > > 'logical' level for backward compatibility and for users who want to
> > > enable the logical decoding without calling that SQL function. If we
> > > can automatically enable the logical decoding when creating the first
> > > logical replication slot, probably we no longer need the 'logical'
> > > level. There is room to discuss the user interface. Feedback is very
> > > welcome.
> > >
> >
> > If a server is running at minimal wal_level and they want to enable
> > logical replication, they would still need a server restart. That
> > would be rare but not completely absent.
>
> Currently we don't allow the server to start with the 'minimal' level
> and max_wal_senders > 0. Even if we support changing 'minimal' to
> 'logical' without a server restart, we still need a server restart to
> increase max_wal_senders for users who want to use logical
> replication. Or we need to eliminate this restriction too. I guess it
> would be too complex for such uncommon use cases.
>
> >
> > Our documentation says "wal_level determines how much information is
> > written to the WAL.". Users would may not expect that the WAL amount
> > changes while wal_level = replica depending upon whether logical
> > decoding is possible. It may be possible to set the expectations right
> > by changing the documentation. It's not in the patch, so I am not sure
> > whether this is considered.
>
> We should mention that in the doc. The WAL amount changes depending on
> not only wal_level but also other parameters such as wal_log_hints and
> full_page_writes.
>
> > Cloud providers do not like multiple ways of changing configuration
> > esp. when they can not control it. See [1]. Changing wal_level through
> > a SQL function may fit the same category.
>
> Thank you for pointing it out. This would support the idea of
> automatically enabling logical decoding.
>
> > I agree that it would be a lot of work to make all combinations of
> > wal_level changes work, but changing wal_level through SIGHUP looks
> > like a cleaner solution. Is there way that we make the GUC SIGHUP but
> > disallow certain combinations of old and new values?
>
> While I agree that it's cleaner I think there is no way today. I think
> we need to invent something for that.

I would like to summarize the proposed approaches thus far:

Regarding the user interface, there are three approaches:

1. Implementing SQL function controls (e.g.,
pg_activate_logical_decoding() and pg_deactivate_logical_decoding()).
This would enable users to activate logical decoding even with
wal_level=replica by calling the SQL function. While cloud providers
seem not like having multiple configuration methods, this could
potentially be managed through appropriate EXECUTE privileges. Another
drawback is the user confusion when 'SHOW wal_level' displays
'replica' despite processes writing WAL records with logical
information. This might be dealt with by implementing a show_hook
function for wal_level.

2. Implementing automatic logical decoding activation. This would
trigger upon creation of the first logical slot and deactivate upon
removal of the final slot. This approach shares the user confusion
concern of the first proposal. Moreover, it presents a significant
limitation: users would be unable to utilize logical decoding on
standby servers without maintaining at least one logical slot on the
primary -- a substantial disadvantage.

3. Converting wal_level to a SIGHUP parameter, thereby supporting all
possible wal_level transition combinations. While this represents the
most elegant solution among the proposals, it necessitates additional
development effort for less common scenarios, such as transitioning
between 'minimal' and 'replica' levels. Such transitions require
specific handling -- for instance, changing between 'minimal' and
'replica' requires a checkpoint, while decreasing from 'replica' to
'minimal' necessitates terminating certain processes like WAL senders
and archiver.

We also had discussion (and I did some research) on the implementation
of increasing/decreasing wal_level online. The basic idea is that we
first enable logical information WAL-logging to all processes while
maintaining the logical decoding in an inactive state. Once we can
guarantee that all processes are writing WAL records with logical
information, we enable the logical decoding. This guarantee can be
achieved by waiting for all concurrent transactions to finish, which
could make us wait for a long time if a transaction is long-running.
Another way is to send a global barrier signal and wait for all
processes to start writing WAL records with logical information. We
have a good facility for that: EmitProcSignalBarrier() and
WaitForProcSignalBarrier(). That way, we don't need to wait for
transaction finishes.

Based on the discussion so far, the idea 3 appears most promising. I
welcome any additional suggestions or preferences.

BTW I'm writing a PoC patch for the idea 3 and using global barriers,
and will share the patch.

Regards,

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


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-23 07:42:48
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Wed, Jan 22, 2025 at 04:46:00PM -0800, Masahiko Sawada wrote:
> I would like to summarize the proposed approaches thus far:

Thanks!

> Regarding the user interface, there are three approaches:
>
> 1. Implementing SQL function controls (e.g.,
> pg_activate_logical_decoding() and pg_deactivate_logical_decoding()).
> This would enable users to activate logical decoding even with
> wal_level=replica by calling the SQL function. While cloud providers
> seem not like having multiple configuration methods, this could
> potentially be managed through appropriate EXECUTE privileges. Another
> drawback is the user confusion when 'SHOW wal_level' displays
> 'replica' despite processes writing WAL records with logical
> information. This might be dealt with by implementing a show_hook
> function for wal_level.
>
> 2. Implementing automatic logical decoding activation. This would
> trigger upon creation of the first logical slot and deactivate upon
> removal of the final slot. This approach shares the user confusion
> concern of the first proposal. Moreover, it presents a significant
> limitation: users would be unable to utilize logical decoding on
> standby servers without maintaining at least one logical slot on the
> primary -- a substantial disadvantage.

Yeah, unless we keep wal_level around but I agree that the following (3.) looks
like the way to go (as it removes any confusion).

> 3. Converting wal_level to a SIGHUP parameter, thereby supporting all
> possible wal_level transition combinations. While this represents the
> most elegant solution among the proposals,

+1

> it necessitates additional
> development effort for less common scenarios, such as transitioning
> between 'minimal' and 'replica' levels. Such transitions require
> specific handling -- for instance, changing between 'minimal' and
> 'replica' requires a checkpoint, while decreasing from 'replica' to
> 'minimal' necessitates terminating certain processes like WAL senders
> and archiver.

Yeah. OTOH switching from replica to minimal is "dangerous" as it makes
previous base backups unusable for point-in-time recovery. So I wonder if it
wouldn't be better to keep a restart mandatory depending of the transition
state (that would probably make users thinking "twice" before doing the
transition that requires a restart). I don't think any GUC does that already but
that might be something to explore, thoughts?

> We also had discussion (and I did some research) on the implementation
> of increasing/decreasing wal_level online. The basic idea is that we
> first enable logical information WAL-logging to all processes while
> maintaining the logical decoding in an inactive state. Once we can
> guarantee that all processes are writing WAL records with logical
> information, we enable the logical decoding. This guarantee can be
> achieved by waiting for all concurrent transactions to finish, which
> could make us wait for a long time if a transaction is long-running.
> Another way is to send a global barrier signal and wait for all
> processes to start writing WAL records with logical information. We
> have a good facility for that: EmitProcSignalBarrier() and
> WaitForProcSignalBarrier(). That way, we don't need to wait for
> transaction finishes.

That sounds like a plan.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-23 11:24:06
Message-ID: CAExHW5s6qzY7FYrx8mSbq_7ebaHa-hQSC7P_Pugp8BNC7wvV-A@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jan 23, 2025 at 6:16 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Fri, Jan 10, 2025 at 12:33 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Thu, Jan 9, 2025 at 3:29 AM Ashutosh Bapat
> > <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> > >
> > > On Tue, Dec 31, 2024 at 10:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > Hi all,
> > > >
> > > > Logical decoding (and logical replication) are available only when
> > > > wal_level = logical. As the documentation says[1], Using the 'logical'
> > > > level increases the WAL volume which could negatively affect the
> > > > performance. For that reason, users might want to start with using
> > > > 'replica', but when they want to use logical decoding they need a
> > > > server restart to increase wal_level to 'logical'. My goal is to allow
> > > > users who are using 'replica' level to use logical decoding without a
> > > > server restart. There are other GUC parameters related to logical
> > > > decoding and logical replication such as max_wal_senders,
> > > > max_logical_replication_workers, and max_replication_slots, but even
> > > > if users set these parameters >0, there would not be a noticeable
> > > > performance impact. And their default values are already >0. So I'd
> > > > like to focus on making only the wal_level dynamic GUC parameter.
> > > > There are several earlier discussions[2][3] but no one has submitted
> > > > patches unless I'm missing something.
> > > >
> > > > The first idea I came up with is to make the wal_level a PGC_SIGHUP
> > > > parameter. However, it affects not only setting 'replica' to 'logical'
> > > > but also setting 'minimal' to 'replica' or higher. I'm not sure the
> > > > latter case is common and it might require a checkpoint. I don't want
> > > > to make the patch complex for uncommon cases.
> > > >
> > > > The second idea is to somehow allow both WAL-logging logical info and
> > > > logical decoding even when wal_level is 'replica'. I've attached a PoC
> > > > patch for that. The patch introduces new SQL functions such as
> > > > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > > > These functions are available only when wal_level is 'repilca'(or
> > > > higher). In pg_activate_logical_decoding(), we set the status of
> > > > logical decoding stored on the shared memory from 'disabled' to
> > > > 'xlog-logical-info', allowing all processes to write logical
> > > > information to WAL records for logical decoding. But the logical
> > > > decoding is still not allowed. Once we confirm all in-progress
> > > > transactions completed, we switch the status to
> > > > 'logical-decoding-ready', meaning that users can create logical
> > > > replication slots and use logical decoding.
> > > >
> > > > Overall, with the patch, there are two ways to enable logical
> > > > decoding: setting wal_level to 'logical' and calling
> > > > pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> > > > 'logical' level for backward compatibility and for users who want to
> > > > enable the logical decoding without calling that SQL function. If we
> > > > can automatically enable the logical decoding when creating the first
> > > > logical replication slot, probably we no longer need the 'logical'
> > > > level. There is room to discuss the user interface. Feedback is very
> > > > welcome.
> > > >
> > >
> > > If a server is running at minimal wal_level and they want to enable
> > > logical replication, they would still need a server restart. That
> > > would be rare but not completely absent.
> >
> > Currently we don't allow the server to start with the 'minimal' level
> > and max_wal_senders > 0. Even if we support changing 'minimal' to
> > 'logical' without a server restart, we still need a server restart to
> > increase max_wal_senders for users who want to use logical
> > replication. Or we need to eliminate this restriction too. I guess it
> > would be too complex for such uncommon use cases.
> >
> > >
> > > Our documentation says "wal_level determines how much information is
> > > written to the WAL.". Users would may not expect that the WAL amount
> > > changes while wal_level = replica depending upon whether logical
> > > decoding is possible. It may be possible to set the expectations right
> > > by changing the documentation. It's not in the patch, so I am not sure
> > > whether this is considered.
> >
> > We should mention that in the doc. The WAL amount changes depending on
> > not only wal_level but also other parameters such as wal_log_hints and
> > full_page_writes.
> >
> > > Cloud providers do not like multiple ways of changing configuration
> > > esp. when they can not control it. See [1]. Changing wal_level through
> > > a SQL function may fit the same category.
> >
> > Thank you for pointing it out. This would support the idea of
> > automatically enabling logical decoding.
> >
> > > I agree that it would be a lot of work to make all combinations of
> > > wal_level changes work, but changing wal_level through SIGHUP looks
> > > like a cleaner solution. Is there way that we make the GUC SIGHUP but
> > > disallow certain combinations of old and new values?
> >
> > While I agree that it's cleaner I think there is no way today. I think
> > we need to invent something for that.
>
> I would like to summarize the proposed approaches thus far:
>
> Regarding the user interface, there are three approaches:
>
> 1. Implementing SQL function controls (e.g.,
> pg_activate_logical_decoding() and pg_deactivate_logical_decoding()).
> This would enable users to activate logical decoding even with
> wal_level=replica by calling the SQL function. While cloud providers
> seem not like having multiple configuration methods, this could
> potentially be managed through appropriate EXECUTE privileges. Another
> drawback is the user confusion when 'SHOW wal_level' displays
> 'replica' despite processes writing WAL records with logical
> information. This might be dealt with by implementing a show_hook
> function for wal_level.
>
> 2. Implementing automatic logical decoding activation. This would
> trigger upon creation of the first logical slot and deactivate upon
> removal of the final slot. This approach shares the user confusion
> concern of the first proposal. Moreover, it presents a significant
> limitation: users would be unable to utilize logical decoding on
> standby servers without maintaining at least one logical slot on the
> primary -- a substantial disadvantage.
>
> 3. Converting wal_level to a SIGHUP parameter, thereby supporting all
> possible wal_level transition combinations. While this represents the
> most elegant solution among the proposals, it necessitates additional
> development effort for less common scenarios, such as transitioning
> between 'minimal' and 'replica' levels. Such transitions require
> specific handling -- for instance, changing between 'minimal' and
> 'replica' requires a checkpoint, while decreasing from 'replica' to
> 'minimal' necessitates terminating certain processes like WAL senders
> and archiver.
>
> We also had discussion (and I did some research) on the implementation
> of increasing/decreasing wal_level online. The basic idea is that we
> first enable logical information WAL-logging to all processes while
> maintaining the logical decoding in an inactive state. Once we can
> guarantee that all processes are writing WAL records with logical
> information, we enable the logical decoding. This guarantee can be
> achieved by waiting for all concurrent transactions to finish, which
> could make us wait for a long time if a transaction is long-running.
> Another way is to send a global barrier signal and wait for all
> processes to start writing WAL records with logical information. We
> have a good facility for that: EmitProcSignalBarrier() and
> WaitForProcSignalBarrier(). That way, we don't need to wait for
> transaction finishes.
>
> Based on the discussion so far, the idea 3 appears most promising. I
> welcome any additional suggestions or preferences.

I think this is the cleanest solution but harder to implement.
Performing any heavy lifting like waiting for other transactions to
finish or a barrier inside pg_reload_conf() increases the chances of
delaying conf reload. Further, if there are errors, it might cause
some configurations to be not loaded. So the actual processing needs
to happen after the configurations have been loaded.

--
Best Wishes,
Ashutosh Bapat


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-24 19:16:18
Message-ID: CAD21AoDYWStjLKk9Q8ex4+XbgGqypbg9xA9QOt8yBWDgc_owXQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jan 23, 2025 at 3:24 AM Ashutosh Bapat
<ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
>
> On Thu, Jan 23, 2025 at 6:16 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Fri, Jan 10, 2025 at 12:33 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Thu, Jan 9, 2025 at 3:29 AM Ashutosh Bapat
> > > <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> > > >
> > > > On Tue, Dec 31, 2024 at 10:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > >
> > > > > Hi all,
> > > > >
> > > > > Logical decoding (and logical replication) are available only when
> > > > > wal_level = logical. As the documentation says[1], Using the 'logical'
> > > > > level increases the WAL volume which could negatively affect the
> > > > > performance. For that reason, users might want to start with using
> > > > > 'replica', but when they want to use logical decoding they need a
> > > > > server restart to increase wal_level to 'logical'. My goal is to allow
> > > > > users who are using 'replica' level to use logical decoding without a
> > > > > server restart. There are other GUC parameters related to logical
> > > > > decoding and logical replication such as max_wal_senders,
> > > > > max_logical_replication_workers, and max_replication_slots, but even
> > > > > if users set these parameters >0, there would not be a noticeable
> > > > > performance impact. And their default values are already >0. So I'd
> > > > > like to focus on making only the wal_level dynamic GUC parameter.
> > > > > There are several earlier discussions[2][3] but no one has submitted
> > > > > patches unless I'm missing something.
> > > > >
> > > > > The first idea I came up with is to make the wal_level a PGC_SIGHUP
> > > > > parameter. However, it affects not only setting 'replica' to 'logical'
> > > > > but also setting 'minimal' to 'replica' or higher. I'm not sure the
> > > > > latter case is common and it might require a checkpoint. I don't want
> > > > > to make the patch complex for uncommon cases.
> > > > >
> > > > > The second idea is to somehow allow both WAL-logging logical info and
> > > > > logical decoding even when wal_level is 'replica'. I've attached a PoC
> > > > > patch for that. The patch introduces new SQL functions such as
> > > > > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > > > > These functions are available only when wal_level is 'repilca'(or
> > > > > higher). In pg_activate_logical_decoding(), we set the status of
> > > > > logical decoding stored on the shared memory from 'disabled' to
> > > > > 'xlog-logical-info', allowing all processes to write logical
> > > > > information to WAL records for logical decoding. But the logical
> > > > > decoding is still not allowed. Once we confirm all in-progress
> > > > > transactions completed, we switch the status to
> > > > > 'logical-decoding-ready', meaning that users can create logical
> > > > > replication slots and use logical decoding.
> > > > >
> > > > > Overall, with the patch, there are two ways to enable logical
> > > > > decoding: setting wal_level to 'logical' and calling
> > > > > pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> > > > > 'logical' level for backward compatibility and for users who want to
> > > > > enable the logical decoding without calling that SQL function. If we
> > > > > can automatically enable the logical decoding when creating the first
> > > > > logical replication slot, probably we no longer need the 'logical'
> > > > > level. There is room to discuss the user interface. Feedback is very
> > > > > welcome.
> > > > >
> > > >
> > > > If a server is running at minimal wal_level and they want to enable
> > > > logical replication, they would still need a server restart. That
> > > > would be rare but not completely absent.
> > >
> > > Currently we don't allow the server to start with the 'minimal' level
> > > and max_wal_senders > 0. Even if we support changing 'minimal' to
> > > 'logical' without a server restart, we still need a server restart to
> > > increase max_wal_senders for users who want to use logical
> > > replication. Or we need to eliminate this restriction too. I guess it
> > > would be too complex for such uncommon use cases.
> > >
> > > >
> > > > Our documentation says "wal_level determines how much information is
> > > > written to the WAL.". Users would may not expect that the WAL amount
> > > > changes while wal_level = replica depending upon whether logical
> > > > decoding is possible. It may be possible to set the expectations right
> > > > by changing the documentation. It's not in the patch, so I am not sure
> > > > whether this is considered.
> > >
> > > We should mention that in the doc. The WAL amount changes depending on
> > > not only wal_level but also other parameters such as wal_log_hints and
> > > full_page_writes.
> > >
> > > > Cloud providers do not like multiple ways of changing configuration
> > > > esp. when they can not control it. See [1]. Changing wal_level through
> > > > a SQL function may fit the same category.
> > >
> > > Thank you for pointing it out. This would support the idea of
> > > automatically enabling logical decoding.
> > >
> > > > I agree that it would be a lot of work to make all combinations of
> > > > wal_level changes work, but changing wal_level through SIGHUP looks
> > > > like a cleaner solution. Is there way that we make the GUC SIGHUP but
> > > > disallow certain combinations of old and new values?
> > >
> > > While I agree that it's cleaner I think there is no way today. I think
> > > we need to invent something for that.
> >
> > I would like to summarize the proposed approaches thus far:
> >
> > Regarding the user interface, there are three approaches:
> >
> > 1. Implementing SQL function controls (e.g.,
> > pg_activate_logical_decoding() and pg_deactivate_logical_decoding()).
> > This would enable users to activate logical decoding even with
> > wal_level=replica by calling the SQL function. While cloud providers
> > seem not like having multiple configuration methods, this could
> > potentially be managed through appropriate EXECUTE privileges. Another
> > drawback is the user confusion when 'SHOW wal_level' displays
> > 'replica' despite processes writing WAL records with logical
> > information. This might be dealt with by implementing a show_hook
> > function for wal_level.
> >
> > 2. Implementing automatic logical decoding activation. This would
> > trigger upon creation of the first logical slot and deactivate upon
> > removal of the final slot. This approach shares the user confusion
> > concern of the first proposal. Moreover, it presents a significant
> > limitation: users would be unable to utilize logical decoding on
> > standby servers without maintaining at least one logical slot on the
> > primary -- a substantial disadvantage.
> >
> > 3. Converting wal_level to a SIGHUP parameter, thereby supporting all
> > possible wal_level transition combinations. While this represents the
> > most elegant solution among the proposals, it necessitates additional
> > development effort for less common scenarios, such as transitioning
> > between 'minimal' and 'replica' levels. Such transitions require
> > specific handling -- for instance, changing between 'minimal' and
> > 'replica' requires a checkpoint, while decreasing from 'replica' to
> > 'minimal' necessitates terminating certain processes like WAL senders
> > and archiver.
> >
> > We also had discussion (and I did some research) on the implementation
> > of increasing/decreasing wal_level online. The basic idea is that we
> > first enable logical information WAL-logging to all processes while
> > maintaining the logical decoding in an inactive state. Once we can
> > guarantee that all processes are writing WAL records with logical
> > information, we enable the logical decoding. This guarantee can be
> > achieved by waiting for all concurrent transactions to finish, which
> > could make us wait for a long time if a transaction is long-running.
> > Another way is to send a global barrier signal and wait for all
> > processes to start writing WAL records with logical information. We
> > have a good facility for that: EmitProcSignalBarrier() and
> > WaitForProcSignalBarrier(). That way, we don't need to wait for
> > transaction finishes.
> >
> > Based on the discussion so far, the idea 3 appears most promising. I
> > welcome any additional suggestions or preferences.
>
> I think this is the cleanest solution but harder to implement.
> Performing any heavy lifting like waiting for other transactions to
> finish or a barrier inside pg_reload_conf() increases the chances of
> delaying conf reload. Further, if there are errors, it might cause
> some configurations to be not loaded. So the actual processing needs
> to happen after the configurations have been loaded.

Here is an idea: we can use a background worker who does everything
for changing wal_level online. I thought we could delegate the work
for changing wal_level to the checkpointer process, but given that the
work involves creating a checkpoint, invalidating logical slots, and
terminating (physical) walsenders etc I think it would be better to
have a dedicated worker for that. I've attached a PoC patch for
discussion. It's still dirty, uncommented, and untested enough, but I
hope it will help move this project forward. In the patch, when the
checkpointer realizes that wal_level has been changed, it launches a
background worker, wal-level control worker. The worker changes
wal_level online using global barriers etc. and terminates
functionality such as WAL archiving, replication and logical decoding
if necessary.

While it might be too much to use a background worker just for
changing wal_level online, I think it's technically okay. Users would
need to have one open background worker slot, or we can implement it
using an auxiliary process. Such a worker process might be able to be
used for other parameters too in the future.

Regards,

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

Attachment Content-Type Size
v1-0001-PoC-Convert-wal_level-a-PGC_SIGHUP-parameter.patch application/octet-stream 42.0 KB

From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-24 19:28:18
Message-ID: CAD21AoA1K+335_+PA3Oyh5+e3n+HhAqSphAfka6cV1uKv+HQFw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jan 22, 2025 at 11:42 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Wed, Jan 22, 2025 at 04:46:00PM -0800, Masahiko Sawada wrote:
> > I would like to summarize the proposed approaches thus far:
>
> Thanks!
>
> > Regarding the user interface, there are three approaches:
> >
> > 1. Implementing SQL function controls (e.g.,
> > pg_activate_logical_decoding() and pg_deactivate_logical_decoding()).
> > This would enable users to activate logical decoding even with
> > wal_level=replica by calling the SQL function. While cloud providers
> > seem not like having multiple configuration methods, this could
> > potentially be managed through appropriate EXECUTE privileges. Another
> > drawback is the user confusion when 'SHOW wal_level' displays
> > 'replica' despite processes writing WAL records with logical
> > information. This might be dealt with by implementing a show_hook
> > function for wal_level.
> >
> > 2. Implementing automatic logical decoding activation. This would
> > trigger upon creation of the first logical slot and deactivate upon
> > removal of the final slot. This approach shares the user confusion
> > concern of the first proposal. Moreover, it presents a significant
> > limitation: users would be unable to utilize logical decoding on
> > standby servers without maintaining at least one logical slot on the
> > primary -- a substantial disadvantage.
>
> Yeah, unless we keep wal_level around but I agree that the following (3.) looks
> like the way to go (as it removes any confusion).
>
> > 3. Converting wal_level to a SIGHUP parameter, thereby supporting all
> > possible wal_level transition combinations. While this represents the
> > most elegant solution among the proposals,
>
> +1
>
> > it necessitates additional
> > development effort for less common scenarios, such as transitioning
> > between 'minimal' and 'replica' levels. Such transitions require
> > specific handling -- for instance, changing between 'minimal' and
> > 'replica' requires a checkpoint, while decreasing from 'replica' to
> > 'minimal' necessitates terminating certain processes like WAL senders
> > and archiver.
>
> Yeah. OTOH switching from replica to minimal is "dangerous" as it makes
> previous base backups unusable for point-in-time recovery. So I wonder if it
> wouldn't be better to keep a restart mandatory depending of the transition
> state (that would probably make users thinking "twice" before doing the
> transition that requires a restart). I don't think any GUC does that already but
> that might be something to explore, thoughts?

I'm concerned that such inconsistency could introduce confusion for
users. The outcome by changing wal_level to minimal is already
documented, and I guess users would check what parameters are going to
be changed even before reloading the config file. I'm not sure that
requiring a server restart only for lowering wal_level to 'minimal'
would really be a protection for unexpectedly making previous base
backups unusable.

It might make sense to raise a WARNING when ALTER SYSTEM lowers the
wal_level to 'minimal'.

Regards,

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


From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: 'Masahiko Sawada' <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: RE: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-28 09:38:57
Message-ID: OSCPR01MB1496669107B3580F7041DACC0F5EF2@OSCPR01MB14966.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Dear Sawada-san,

I love the idea. I've roughly tested the patch and worked on my env.
Here are initial comments...

1. xloglevelworker.c
```
+#include "replication/logicalxlog.h"
```

xloglevelworker.c includes replication/logicalxlog.h, but it does not exist.
The line had to be removed to build and test it.

2.
```
+static void
+writeUpdateWalLevel(int new_wal_level)
+{
+ XLogBeginInsert();
+ XLogRegisterData((char *) (&new_wal_level), sizeof(bool));
+ XLogInsert(RM_XLOG_ID, XLOG_UPDATE_WAL_LEVEL);
+}
```

IIUC the data length should be sizeof(int) instead of sizeof(bool).

3.
Is there a reason why the process does not wait till the archiver exits?

4.
When I dumped wal files, I found that XLOG_UPDATE_WAL_LEVEL cannot be recognized:

```
rmgr: XLOG len (rec/tot): 27/ 27, tx: 0, lsn: 0/03050838, prev 0/03050800, desc: UNKNOWN (f0) wal_level logical
```

xlog_identify() must be updated as well.

5.
When I changed "logical" to "replica", postgres outputs like below:

```
LOG: received SIGHUP, reloading configuration files
LOG: parameter "wal_level" changed to "replica"
LOG: wal_level control worker started
LOG: changing wal_level from "logical" to "replica"
LOG: wal_level has been decreased to "replica"
LOG: successfully changed wal_level from "logical" to "replica"
```

ISTM that both postmaster and the wal_level control worker said something like
"wal_level changed", which is bit strange for me. Since GUC can't be renamed,
can we use another name for the wal_level control state?

6.
With the patch present, the wal_level can be changed to the minimal even when the
streaming replication is going. If we do that, the walsender exits immediately and
the below FATAL appears periodically until the standby stops. Same things can be
said for the logical replication:

```
FATAL: streaming replication receiver "walreceiver" could not connect to the primary server:
connection to server on socket "/tmp/.s.PGSQL.oooo" failed:
FATAL: WAL senders require "wal_level" to be "replica" or "logical
```

I know this is not a perfect, but can we avoid the issue by reject the GUC update
if the walsender exists? Another approach is not to update the value when replication
slots need to be invalidated.

----------
Best regards,
Haato Kuroda


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-01-29 00:09:32
Message-ID: CAD21AoADdcgjRgH9kyJnAAe_dkoxPx8DKwGA0PfVx6_qjADz=g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jan 28, 2025 at 1:39 AM Hayato Kuroda (Fujitsu)
<kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
>
> Dear Sawada-san,
>
> I love the idea. I've roughly tested the patch and worked on my env.
> Here are initial comments...

Thank you for looking at the patch!

>
> 1. xloglevelworker.c
> ```
> +#include "replication/logicalxlog.h"
> ```
>
> xloglevelworker.c includes replication/logicalxlog.h, but it does not exist.
> The line had to be removed to build and test it.
>
> 2.
> ```
> +static void
> +writeUpdateWalLevel(int new_wal_level)
> +{
> + XLogBeginInsert();
> + XLogRegisterData((char *) (&new_wal_level), sizeof(bool));
> + XLogInsert(RM_XLOG_ID, XLOG_UPDATE_WAL_LEVEL);
> +}
> ```
>
> IIUC the data length should be sizeof(int) instead of sizeof(bool).

Agreed to fix them.

>
> 3.
> Is there a reason why the process does not wait till the archiver exits?

No. I didn't implement this part as the patch was just for
proof-of-concept. I think it would be better to wait for it to exit.

>
> 4.
> When I dumped wal files, I found that XLOG_UPDATE_WAL_LEVEL cannot be recognized:
>
> ```
> rmgr: XLOG len (rec/tot): 27/ 27, tx: 0, lsn: 0/03050838, prev 0/03050800, desc: UNKNOWN (f0) wal_level logical
> ```
>
> xlog_identify() must be updated as well.

Will fix.

>
> 5.
> When I changed "logical" to "replica", postgres outputs like below:
>
> ```
> LOG: received SIGHUP, reloading configuration files
> LOG: parameter "wal_level" changed to "replica"
> LOG: wal_level control worker started
> LOG: changing wal_level from "logical" to "replica"
> LOG: wal_level has been decreased to "replica"
> LOG: successfully changed wal_level from "logical" to "replica"
> ```
>
> ISTM that both postmaster and the wal_level control worker said something like
> "wal_level changed", which is bit strange for me. Since GUC can't be renamed,
> can we use another name for the wal_level control state?

I'm concerned that users could be confused if two different names
refer to substantially the same thing.

Having said that, I guess that we need to drastically change the
messages. For example, I think that the wal_level worker should say
something like "successfully made 'logical' wal_level effective"
instead of saying something like "changed wal_level value". Also,
users might not need gradual messages when increasing 'minimal' to
'logical' or decreasing 'logical' to 'minimal'.

>
> 6.
> With the patch present, the wal_level can be changed to the minimal even when the
> streaming replication is going. If we do that, the walsender exits immediately and
> the below FATAL appears periodically until the standby stops. Same things can be
> said for the logical replication:
>
> ```
> FATAL: streaming replication receiver "walreceiver" could not connect to the primary server:
> connection to server on socket "/tmp/.s.PGSQL.oooo" failed:
> FATAL: WAL senders require "wal_level" to be "replica" or "logical
> ```
>
> I know this is not a perfect, but can we avoid the issue by reject the GUC update
> if the walsender exists? Another approach is not to update the value when replication
> slots need to be invalidated.

Does it mean that we reject the config file from being reloaded in
that case? I have no idea how to reject it in a case where the
wal_level in postgresql.conf changed and the user did 'pg_ctl reload'.

Regards,

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


From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: 'Masahiko Sawada' <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: RE: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-03 11:40:13
Message-ID: OSCPR01MB14966A23A7BF518C0BAF5B284F5F52@OSCPR01MB14966.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Dear Sawada-san,

> I'm concerned that users could be confused if two different names
> refer to substantially the same thing.
>
> Having said that, I guess that we need to drastically change the
> messages. For example, I think that the wal_level worker should say
> something like "successfully made 'logical' wal_level effective"
> instead of saying something like "changed wal_level value". Also,
> users might not need gradual messages when increasing 'minimal' to
> 'logical' or decreasing 'logical' to 'minimal'.

+1 for something like "successfully made 'logical' wal_level effective", and
removing gradual messages.

> > 6.
> > With the patch present, the wal_level can be changed to the minimal even when
> the
> > streaming replication is going. If we do that, the walsender exits immediately
> and
> > the below FATAL appears periodically until the standby stops. Same things can
> be
> > said for the logical replication:
> >
> > ```
> > FATAL: streaming replication receiver "walreceiver" could not connect to the
> primary server:
> > connection to server on socket "/tmp/.s.PGSQL.oooo" failed:
> > FATAL: WAL senders require "wal_level" to be "replica" or "logical
> > ```
> >
> > I know this is not a perfect, but can we avoid the issue by reject the GUC update
> > if the walsender exists? Another approach is not to update the value when
> replication
> > slots need to be invalidated.
>
> Does it mean that we reject the config file from being reloaded in
> that case? I have no idea how to reject it in a case where the
> wal_level in postgresql.conf changed and the user did 'pg_ctl reload'.

I imagined like attached. When I modified wal_level to minimal and send SIGHUP,
postmaster reported below lines and failed to update wal_level.

```
LOG: received SIGHUP, reloading configuration files
LOG: wal_level cannot be set to "minimal" while walsender exists
LOG: configuration file "...postgresql.conf" contains errors; unaffected changes were applied
```

Best regards,
Hayato Kuroda
FUJITSU LIMITED

Attachment Content-Type Size
add_check_hook.patch application/octet-stream 3.2 KB

From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-04 08:15:29
Message-ID: CAD21AoCOvPoCmwja6dROP3CYsA_KWMiLQGuPyDm7T0Wg+rV9zw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Feb 3, 2025 at 3:40 AM Hayato Kuroda (Fujitsu)
<kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
>
> Dear Sawada-san,
>
> > I'm concerned that users could be confused if two different names
> > refer to substantially the same thing.
> >
> > Having said that, I guess that we need to drastically change the
> > messages. For example, I think that the wal_level worker should say
> > something like "successfully made 'logical' wal_level effective"
> > instead of saying something like "changed wal_level value". Also,
> > users might not need gradual messages when increasing 'minimal' to
> > 'logical' or decreasing 'logical' to 'minimal'.
>
> +1 for something like "successfully made 'logical' wal_level effective", and
> removing gradual messages.
>
> > > 6.
> > > With the patch present, the wal_level can be changed to the minimal even when
> > the
> > > streaming replication is going. If we do that, the walsender exits immediately
> > and
> > > the below FATAL appears periodically until the standby stops. Same things can
> > be
> > > said for the logical replication:
> > >
> > > ```
> > > FATAL: streaming replication receiver "walreceiver" could not connect to the
> > primary server:
> > > connection to server on socket "/tmp/.s.PGSQL.oooo" failed:
> > > FATAL: WAL senders require "wal_level" to be "replica" or "logical
> > > ```
> > >
> > > I know this is not a perfect, but can we avoid the issue by reject the GUC update
> > > if the walsender exists? Another approach is not to update the value when
> > replication
> > > slots need to be invalidated.
> >
> > Does it mean that we reject the config file from being reloaded in
> > that case? I have no idea how to reject it in a case where the
> > wal_level in postgresql.conf changed and the user did 'pg_ctl reload'.
>
> I imagined like attached. When I modified wal_level to minimal and send SIGHUP,
> postmaster reported below lines and failed to update wal_level.
>
> ```
> LOG: received SIGHUP, reloading configuration files
> LOG: wal_level cannot be set to "minimal" while walsender exists
> LOG: configuration file "...postgresql.conf" contains errors; unaffected changes were applied
> ```

Interesting, and thanks for sharing the patch. But I think that when
we change the wal_level to 'minimal', there is a window where a new
walsender can launch after passing the check_wal_level() check.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-11 22:11:10
Message-ID: CAD21AoAxHgkYnwRptA=3rQVqotwadEvpxmetBFT5KqrGbRxv+Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jan 24, 2025 at 11:16 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Jan 23, 2025 at 3:24 AM Ashutosh Bapat
> <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> >
> > On Thu, Jan 23, 2025 at 6:16 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Fri, Jan 10, 2025 at 12:33 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Thu, Jan 9, 2025 at 3:29 AM Ashutosh Bapat
> > > > <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Tue, Dec 31, 2024 at 10:15 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > Hi all,
> > > > > >
> > > > > > Logical decoding (and logical replication) are available only when
> > > > > > wal_level = logical. As the documentation says[1], Using the 'logical'
> > > > > > level increases the WAL volume which could negatively affect the
> > > > > > performance. For that reason, users might want to start with using
> > > > > > 'replica', but when they want to use logical decoding they need a
> > > > > > server restart to increase wal_level to 'logical'. My goal is to allow
> > > > > > users who are using 'replica' level to use logical decoding without a
> > > > > > server restart. There are other GUC parameters related to logical
> > > > > > decoding and logical replication such as max_wal_senders,
> > > > > > max_logical_replication_workers, and max_replication_slots, but even
> > > > > > if users set these parameters >0, there would not be a noticeable
> > > > > > performance impact. And their default values are already >0. So I'd
> > > > > > like to focus on making only the wal_level dynamic GUC parameter.
> > > > > > There are several earlier discussions[2][3] but no one has submitted
> > > > > > patches unless I'm missing something.
> > > > > >
> > > > > > The first idea I came up with is to make the wal_level a PGC_SIGHUP
> > > > > > parameter. However, it affects not only setting 'replica' to 'logical'
> > > > > > but also setting 'minimal' to 'replica' or higher. I'm not sure the
> > > > > > latter case is common and it might require a checkpoint. I don't want
> > > > > > to make the patch complex for uncommon cases.
> > > > > >
> > > > > > The second idea is to somehow allow both WAL-logging logical info and
> > > > > > logical decoding even when wal_level is 'replica'. I've attached a PoC
> > > > > > patch for that. The patch introduces new SQL functions such as
> > > > > > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > > > > > These functions are available only when wal_level is 'repilca'(or
> > > > > > higher). In pg_activate_logical_decoding(), we set the status of
> > > > > > logical decoding stored on the shared memory from 'disabled' to
> > > > > > 'xlog-logical-info', allowing all processes to write logical
> > > > > > information to WAL records for logical decoding. But the logical
> > > > > > decoding is still not allowed. Once we confirm all in-progress
> > > > > > transactions completed, we switch the status to
> > > > > > 'logical-decoding-ready', meaning that users can create logical
> > > > > > replication slots and use logical decoding.
> > > > > >
> > > > > > Overall, with the patch, there are two ways to enable logical
> > > > > > decoding: setting wal_level to 'logical' and calling
> > > > > > pg_activate_logical_decoding() when wal_level is 'replica'. I left the
> > > > > > 'logical' level for backward compatibility and for users who want to
> > > > > > enable the logical decoding without calling that SQL function. If we
> > > > > > can automatically enable the logical decoding when creating the first
> > > > > > logical replication slot, probably we no longer need the 'logical'
> > > > > > level. There is room to discuss the user interface. Feedback is very
> > > > > > welcome.
> > > > > >
> > > > >
> > > > > If a server is running at minimal wal_level and they want to enable
> > > > > logical replication, they would still need a server restart. That
> > > > > would be rare but not completely absent.
> > > >
> > > > Currently we don't allow the server to start with the 'minimal' level
> > > > and max_wal_senders > 0. Even if we support changing 'minimal' to
> > > > 'logical' without a server restart, we still need a server restart to
> > > > increase max_wal_senders for users who want to use logical
> > > > replication. Or we need to eliminate this restriction too. I guess it
> > > > would be too complex for such uncommon use cases.
> > > >
> > > > >
> > > > > Our documentation says "wal_level determines how much information is
> > > > > written to the WAL.". Users would may not expect that the WAL amount
> > > > > changes while wal_level = replica depending upon whether logical
> > > > > decoding is possible. It may be possible to set the expectations right
> > > > > by changing the documentation. It's not in the patch, so I am not sure
> > > > > whether this is considered.
> > > >
> > > > We should mention that in the doc. The WAL amount changes depending on
> > > > not only wal_level but also other parameters such as wal_log_hints and
> > > > full_page_writes.
> > > >
> > > > > Cloud providers do not like multiple ways of changing configuration
> > > > > esp. when they can not control it. See [1]. Changing wal_level through
> > > > > a SQL function may fit the same category.
> > > >
> > > > Thank you for pointing it out. This would support the idea of
> > > > automatically enabling logical decoding.
> > > >
> > > > > I agree that it would be a lot of work to make all combinations of
> > > > > wal_level changes work, but changing wal_level through SIGHUP looks
> > > > > like a cleaner solution. Is there way that we make the GUC SIGHUP but
> > > > > disallow certain combinations of old and new values?
> > > >
> > > > While I agree that it's cleaner I think there is no way today. I think
> > > > we need to invent something for that.
> > >
> > > I would like to summarize the proposed approaches thus far:
> > >
> > > Regarding the user interface, there are three approaches:
> > >
> > > 1. Implementing SQL function controls (e.g.,
> > > pg_activate_logical_decoding() and pg_deactivate_logical_decoding()).
> > > This would enable users to activate logical decoding even with
> > > wal_level=replica by calling the SQL function. While cloud providers
> > > seem not like having multiple configuration methods, this could
> > > potentially be managed through appropriate EXECUTE privileges. Another
> > > drawback is the user confusion when 'SHOW wal_level' displays
> > > 'replica' despite processes writing WAL records with logical
> > > information. This might be dealt with by implementing a show_hook
> > > function for wal_level.
> > >
> > > 2. Implementing automatic logical decoding activation. This would
> > > trigger upon creation of the first logical slot and deactivate upon
> > > removal of the final slot. This approach shares the user confusion
> > > concern of the first proposal. Moreover, it presents a significant
> > > limitation: users would be unable to utilize logical decoding on
> > > standby servers without maintaining at least one logical slot on the
> > > primary -- a substantial disadvantage.
> > >
> > > 3. Converting wal_level to a SIGHUP parameter, thereby supporting all
> > > possible wal_level transition combinations. While this represents the
> > > most elegant solution among the proposals, it necessitates additional
> > > development effort for less common scenarios, such as transitioning
> > > between 'minimal' and 'replica' levels. Such transitions require
> > > specific handling -- for instance, changing between 'minimal' and
> > > 'replica' requires a checkpoint, while decreasing from 'replica' to
> > > 'minimal' necessitates terminating certain processes like WAL senders
> > > and archiver.
> > >
> > > We also had discussion (and I did some research) on the implementation
> > > of increasing/decreasing wal_level online. The basic idea is that we
> > > first enable logical information WAL-logging to all processes while
> > > maintaining the logical decoding in an inactive state. Once we can
> > > guarantee that all processes are writing WAL records with logical
> > > information, we enable the logical decoding. This guarantee can be
> > > achieved by waiting for all concurrent transactions to finish, which
> > > could make us wait for a long time if a transaction is long-running.
> > > Another way is to send a global barrier signal and wait for all
> > > processes to start writing WAL records with logical information. We
> > > have a good facility for that: EmitProcSignalBarrier() and
> > > WaitForProcSignalBarrier(). That way, we don't need to wait for
> > > transaction finishes.
> > >
> > > Based on the discussion so far, the idea 3 appears most promising. I
> > > welcome any additional suggestions or preferences.
> >
> > I think this is the cleanest solution but harder to implement.
> > Performing any heavy lifting like waiting for other transactions to
> > finish or a barrier inside pg_reload_conf() increases the chances of
> > delaying conf reload. Further, if there are errors, it might cause
> > some configurations to be not loaded. So the actual processing needs
> > to happen after the configurations have been loaded.
>
> Here is an idea: we can use a background worker who does everything
> for changing wal_level online. I thought we could delegate the work
> for changing wal_level to the checkpointer process, but given that the
> work involves creating a checkpoint, invalidating logical slots, and
> terminating (physical) walsenders etc I think it would be better to
> have a dedicated worker for that. I've attached a PoC patch for
> discussion. It's still dirty, uncommented, and untested enough, but I
> hope it will help move this project forward. In the patch, when the
> checkpointer realizes that wal_level has been changed, it launches a
> background worker, wal-level control worker. The worker changes
> wal_level online using global barriers etc. and terminates
> functionality such as WAL archiving, replication and logical decoding
> if necessary.
>
> While it might be too much to use a background worker just for
> changing wal_level online, I think it's technically okay. Users would
> need to have one open background worker slot, or we can implement it
> using an auxiliary process. Such a worker process might be able to be
> used for other parameters too in the future.

I've updated the patch that includes comment updates and bug fixes.

The main idea of changing WAL level online is to decouple two aspects:
(1) the information included in WAL records and (2) the
functionalities available at each WAL level. With that, we can change
the WAL level gradually. For example, when increasing the WAL level
from 'replica' to 'logical', we first switch the WAL level on the
shared memory to a new higher level where we allow processes to write
WAL records with additional information required by the logical
decoding, while keeping the logical decoding unavailable. The new
level is something between 'replica' and 'logical'. Once we confirm
all processes have synchronized to the new level, we increase the WAL
level further to 'logical', allowing us to start logical decoding. The
patch supports all combinations of WAL level transitions. It makes
sense to me to use a background worker to proceed with this transition
work since we need to wait at some points, rather than delegating it
to the checkpointer process.

With the patch, wal_level global variable is no longer reliable to get
the actual WAL level since it introduces the authoritative WAL level
is stored in the shared memory that is protected by a lwlock. However,
processes cache flags about the information they need to include to
the WAL records so they don't need to access the shared memory if they
check XLogStandbyInfoActive() or XLogLogicalInfoActive(). The cache is
updated when the process startup or absorbing the global signal
barrier. On the other hand, if they need to check the current active
WAL level, they need to get the WAL level using GetActiveWalLevel()
that accesses the shared memory with locks. The reason I made such
changes is that while the information (1) could be accessed very
frequently for example every XLOG_HEAP_INSERT insertion (via
RelationIsAccessibleInLogicalDecoding()), the information (2) is not
(for example when starting the logical decoding).

Regards,

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

Attachment Content-Type Size
v2-0001-PoC-Convert-wal_level-a-PGC_SIGHUP-parameter.patch application/octet-stream 52.0 KB

From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-12 07:44:38
Message-ID: Z6xRZmnbE/3hFNB/@ip-10-97-1-34.eu-west-3.compute.internal
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Tue, Feb 11, 2025 at 02:11:10PM -0800, Masahiko Sawada wrote:
> I've updated the patch that includes comment updates and bug fixes.

Thanks!

> The main idea of changing WAL level online is to decouple two aspects:
> (1) the information included in WAL records and (2) the
> functionalities available at each WAL level. With that, we can change
> the WAL level gradually. For example, when increasing the WAL level
> from 'replica' to 'logical', we first switch the WAL level on the
> shared memory to a new higher level where we allow processes to write
> WAL records with additional information required by the logical
> decoding, while keeping the logical decoding unavailable. The new
> level is something between 'replica' and 'logical'. Once we confirm
> all processes have synchronized to the new level, we increase the WAL
> level further to 'logical', allowing us to start logical decoding. The
> patch supports all combinations of WAL level transitions. It makes
> sense to me to use a background worker to proceed with this transition
> work since we need to wait at some points, rather than delegating it
> to the checkpointer process.

The background worker being added is "wal_level control worker". I wonder if
it would make sense to create a more "generic" one instead (to whom we could
assign more "tasks" later on, as suggested in the past in [1]).

+ /*
+ * XXX: Perhaps it's not okay that we failed to launch a bgworker and give
+ * up wal_level change because we already reported that the change has
+ * been accepted. Do we need to use aux process instead for that purpose?
+ */
+ if (!RegisterDynamicBackgroundWorker(&bgw, &bgw_handle))
+ ereport(WARNING,
+ (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
+ errmsg("out of background worker slots"),
+ errhint("You might need to increase \"%s\".", "max_worker_processes")));

Not sure it has to be an aux process instead as it should be busy in rare occasions.

Maybe we could add some mechanism for ensuring that a bgworker slot is available
when needed (as suggested in [2])?

Not saying it has to be done that way. I just thought that the "wal_level control worker"
could be a perfect use case/starting point for a more generic one but I don't want
to over complicate that thread though.

So maybe just rename "wal_level control worker" to say "custodian worker" and
we could also think about [2]? Feel free to consider all of this as Nits if you
feel it deviates too much from the initial intend of this thread.

[1]: https://www.postgresql.org/message-id/flat/C1EE64B0-D4DB-40F3-98C8-0CED324D34CB%40amazon.com
[2]: https://www.postgresql.org/message-id/1058306.1680467858%40sss.pgh.pa.us

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-14 08:17:48
Message-ID: CAD21AoBBy11ny-tNT+W=XN0twc6_M=wCi64UmsRSfTzvjy9zVQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Feb 11, 2025 at 11:44 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Tue, Feb 11, 2025 at 02:11:10PM -0800, Masahiko Sawada wrote:
> > I've updated the patch that includes comment updates and bug fixes.
>
> Thanks!
>
> > The main idea of changing WAL level online is to decouple two aspects:
> > (1) the information included in WAL records and (2) the
> > functionalities available at each WAL level. With that, we can change
> > the WAL level gradually. For example, when increasing the WAL level
> > from 'replica' to 'logical', we first switch the WAL level on the
> > shared memory to a new higher level where we allow processes to write
> > WAL records with additional information required by the logical
> > decoding, while keeping the logical decoding unavailable. The new
> > level is something between 'replica' and 'logical'. Once we confirm
> > all processes have synchronized to the new level, we increase the WAL
> > level further to 'logical', allowing us to start logical decoding. The
> > patch supports all combinations of WAL level transitions. It makes
> > sense to me to use a background worker to proceed with this transition
> > work since we need to wait at some points, rather than delegating it
> > to the checkpointer process.
>
> The background worker being added is "wal_level control worker". I wonder if
> it would make sense to create a more "generic" one instead (to whom we could
> assign more "tasks" later on, as suggested in the past in [1]).
>
> + /*
> + * XXX: Perhaps it's not okay that we failed to launch a bgworker and give
> + * up wal_level change because we already reported that the change has
> + * been accepted. Do we need to use aux process instead for that purpose?
> + */
> + if (!RegisterDynamicBackgroundWorker(&bgw, &bgw_handle))
> + ereport(WARNING,
> + (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
> + errmsg("out of background worker slots"),
> + errhint("You might need to increase \"%s\".", "max_worker_processes")));
>
> Not sure it has to be an aux process instead as it should be busy in rare occasions.

Thank you for referring to the custodian worker thread. I'm not sure
that online wal_level change work would fit the concept of custodian
worker, which offloads some work for time-critical works such as
checkpointing, but this idea made me think of other possible
directions of this work.

Looking at the latest custodian worker patch, the basic architecture
is to have a single custodian worker and processes can ask it for some
work such as removing logical decoding related files. The online
wal_level change will be the one of the tasks that processes (eps.
checkpointer) can ask for it. On the other hand, one point that I
think might not fit this wal_level work well is that while the
custodian worker is a long-lived worker process, it's sufficient for
the online wal_level change work to have a bgworker that does its work
and then exits. IOW, from the perspective of this work, I prefer the
idea of having one short-lived worker for one task over having one
long-lived worker for multiple tasks. Reading that thread, while we
need to resolve the XID wraparound issue for the work of removing
logical decoding related files, the work of removing temporary files
seems to fit a short-lived worker style. So I thought as one of the
directions, it might be worth considering to have an infrastructure
where we can launch a bgworker just for one task, and we implement the
online wal_level change and temporary files removal on top of it.

> Maybe we could add some mechanism for ensuring that a bgworker slot is available
> when needed (as suggested in [2])?

Yeah, we need this mechanism if we use a bgworker for these works.

Regards,

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


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-14 10:35:52
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Fri, Feb 14, 2025 at 12:17:48AM -0800, Masahiko Sawada wrote:
> On Tue, Feb 11, 2025 at 11:44 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:

> Looking at the latest custodian worker patch, the basic architecture
> is to have a single custodian worker and processes can ask it for some
> work such as removing logical decoding related files. The online
> wal_level change will be the one of the tasks that processes (eps.
> checkpointer) can ask for it. On the other hand, one point that I
> think might not fit this wal_level work well is that while the
> custodian worker is a long-lived worker process,

That was the case initialy but it looks like it would not have been the case
at the end. See, Tom's comment in [1]:

"
I wonder if a single long-lived custodian task is the right model at all.
At least for RemovePgTempFiles, it'd make more sense to write it as a
background worker that spawns, does its work, and then exits,
independently of anything else
"

> it's sufficient for
> the online wal_level change work to have a bgworker that does its work
> and then exits.

Fully agree and I did not think about changing this behavior.

> IOW, from the perspective of this work, I prefer the
> idea of having one short-lived worker for one task over having one
> long-lived worker for multiple tasks.

Yeah, or one short-lived worker for multiple tasks could work too. It just
starts when it has something to do and then exit.

> Reading that thread, while we
> need to resolve the XID wraparound issue for the work of removing
> logical decoding related files, the work of removing temporary files
> seems to fit a short-lived worker style. So I thought as one of the
> directions, it might be worth considering to have an infrastructure
> where we can launch a bgworker just for one task, and we implement the
> online wal_level change and temporary files removal on top of it.

Yeap, that was exactly my point when I mentioned the custodian thread (taking
into account Tom's comment quoted above).

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-17 20:07:56
Message-ID: CAD21AoCPc+pEgb0pJeiS2CU39ad8VW-10Ze7Uii=1RRjfgQ0uw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Feb 14, 2025 at 2:35 AM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Fri, Feb 14, 2025 at 12:17:48AM -0800, Masahiko Sawada wrote:
> > On Tue, Feb 11, 2025 at 11:44 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> > Looking at the latest custodian worker patch, the basic architecture
> > is to have a single custodian worker and processes can ask it for some
> > work such as removing logical decoding related files. The online
> > wal_level change will be the one of the tasks that processes (eps.
> > checkpointer) can ask for it. On the other hand, one point that I
> > think might not fit this wal_level work well is that while the
> > custodian worker is a long-lived worker process,
>
> That was the case initialy but it looks like it would not have been the case
> at the end. See, Tom's comment in [1]:
>
> "
> I wonder if a single long-lived custodian task is the right model at all.
> At least for RemovePgTempFiles, it'd make more sense to write it as a
> background worker that spawns, does its work, and then exits,
> independently of anything else
> "
>
> > it's sufficient for
> > the online wal_level change work to have a bgworker that does its work
> > and then exits.
>
> Fully agree and I did not think about changing this behavior.
>
> > IOW, from the perspective of this work, I prefer the
> > idea of having one short-lived worker for one task over having one
> > long-lived worker for multiple tasks.
>
> Yeah, or one short-lived worker for multiple tasks could work too. It just
> starts when it has something to do and then exit.
>
> > Reading that thread, while we
> > need to resolve the XID wraparound issue for the work of removing
> > logical decoding related files, the work of removing temporary files
> > seems to fit a short-lived worker style. So I thought as one of the
> > directions, it might be worth considering to have an infrastructure
> > where we can launch a bgworker just for one task, and we implement the
> > online wal_level change and temporary files removal on top of it.
>
> Yeap, that was exactly my point when I mentioned the custodian thread (taking
> into account Tom's comment quoted above).
>

I've written PoC patches to have the online wal_level change work use
a more generic infrastructure. These patches are still in PoC state
but seem like a good direction to me. Here is a brief explanation for
each patch.

* The 0001 patch introduces "reserved background worker slots". We
allocate max_process_workers + BGWORKER_CLASS_RESERVED at startup, and
if the number of running bgworker exceeds max_worker_processes, only
workers using the reserved slots can be launched. We can request to
use the reserved slots by adding BGWORKER_CLASS_RESERVED flag at
bgworker registration.

* The 0002 patch introduces "bgtask worker". The bgtask infrastructure
is designed to execute internal tasks in background in
one-worker-per-one-task style. Internally, bgtask workers use the
reserved bgworker so it's guaranteed that they can launch. The
internal tasks that we can request are predefined and this patch has a
dummy task as a placeholder. This patch implements only the minimal
functionality for the online wal_level change work. I've not tested if
this bgtask infrastructure can be used for tasks that we wanted to
offload to the custodian worker.

* The 0003 patch makes wal_level a SIGHUP parameter. We do the online
wal_level change work using the bgtask infrastructure. There are no
major changes from the previous version other than that.

Regards,

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

Attachment Content-Type Size
v3-0003-PoC-Convert-wal_level-a-PGC_SIGHUP-parameter.patch application/x-patch 49.9 KB
v3-0002-Introduce-bgtask-infrastructure-to-perform-tasks-.patch application/x-patch 12.5 KB
v3-0001-Introduce-reserved-background-worker-slots.patch application/x-patch 19.0 KB

From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-19 09:56:18
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Mon, Feb 17, 2025 at 12:07:56PM -0800, Masahiko Sawada wrote:
> On Fri, Feb 14, 2025 at 2:35 AM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > Yeap, that was exactly my point when I mentioned the custodian thread (taking
> > into account Tom's comment quoted above).
> >
>
> I've written PoC patches to have the online wal_level change work use
> a more generic infrastructure. These patches are still in PoC state
> but seem like a good direction to me. Here is a brief explanation for
> each patch.

Thanks for the patches!

> * The 0001 patch introduces "reserved background worker slots". We
> allocate max_process_workers + BGWORKER_CLASS_RESERVED at startup, and
> if the number of running bgworker exceeds max_worker_processes, only
> workers using the reserved slots can be launched. We can request to
> use the reserved slots by adding BGWORKER_CLASS_RESERVED flag at
> bgworker registration.

I had a quick look at 0001 and I think the way that's implemented is reasonnable.
I thought this could be defined through a GUC so that extensions can benefit
from it. But OTOH the core code should ensure the value is > as the number of
reserved slots needed by the core so not using a GUC looks ok to me.

> * The 0002 patch introduces "bgtask worker". The bgtask infrastructure
> is designed to execute internal tasks in background in
> one-worker-per-one-task style. Internally, bgtask workers use the
> reserved bgworker so it's guaranteed that they can launch.

Yeah.

> The
> internal tasks that we can request are predefined and this patch has a
> dummy task as a placeholder. This patch implements only the minimal
> functionality for the online wal_level change work. I've not tested if
> this bgtask infrastructure can be used for tasks that we wanted to
> offload to the custodian worker.

Again, I had a quick look and looks simple enough of our need here. It "just"
executes "(void) InternalBgTasks[type].func()" and then exists. That's, I think,
a good starting point to add more tasks in the future (if we want to).

> * The 0003 patch makes wal_level a SIGHUP parameter. We do the online
> wal_level change work using the bgtask infrastructure. There are no
> major changes from the previous version other than that.

It replaces the dummy task introduced in 0002 by the one that suits our needs
here (through the new BgTaskWalLevelChange() function).

The design looks reasonable to me. Waiting to see if others disagree before
looking more closely at the code.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-02-20 18:05:20
Message-ID: CAD21AoCcbA8gahmzKVC-+zSBJQdrrw9fghvki_0ANaa11Dmd8g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Feb 19, 2025 at 1:56 AM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,

Thank you for looking at the patches.

>
> On Mon, Feb 17, 2025 at 12:07:56PM -0800, Masahiko Sawada wrote:
> > On Fri, Feb 14, 2025 at 2:35 AM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > Yeap, that was exactly my point when I mentioned the custodian thread (taking
> > > into account Tom's comment quoted above).
> > >
> >
> > I've written PoC patches to have the online wal_level change work use
> > a more generic infrastructure. These patches are still in PoC state
> > but seem like a good direction to me. Here is a brief explanation for
> > each patch.
>
> Thanks for the patches!
>
> > * The 0001 patch introduces "reserved background worker slots". We
> > allocate max_process_workers + BGWORKER_CLASS_RESERVED at startup, and
> > if the number of running bgworker exceeds max_worker_processes, only
> > workers using the reserved slots can be launched. We can request to
> > use the reserved slots by adding BGWORKER_CLASS_RESERVED flag at
> > bgworker registration.
>
> I had a quick look at 0001 and I think the way that's implemented is reasonnable.
> I thought this could be defined through a GUC so that extensions can benefit
> from it. But OTOH the core code should ensure the value is > as the number of
> reserved slots needed by the core so not using a GUC looks ok to me.

Interesting idea. I kept the reserved slots only for internal use but
it would be worth considering to use GUC instead.

> > * The 0002 patch introduces "bgtask worker". The bgtask infrastructure
> > is designed to execute internal tasks in background in
> > one-worker-per-one-task style. Internally, bgtask workers use the
> > reserved bgworker so it's guaranteed that they can launch.
>
> Yeah.
>
> > The
> > internal tasks that we can request are predefined and this patch has a
> > dummy task as a placeholder. This patch implements only the minimal
> > functionality for the online wal_level change work. I've not tested if
> > this bgtask infrastructure can be used for tasks that we wanted to
> > offload to the custodian worker.
>
> Again, I had a quick look and looks simple enough of our need here. It "just"
> executes "(void) InternalBgTasks[type].func()" and then exists. That's, I think,
> a good starting point to add more tasks in the future (if we want to).

Yeah, we might want to extend it further, for example to pass an
argument to the background task or to ask multiple tasks for the
single bgtask worker. As far as I can read the custodian patch set,
the work of removing temp files seems not to require any argument
though.

>
> > * The 0003 patch makes wal_level a SIGHUP parameter. We do the online
> > wal_level change work using the bgtask infrastructure. There are no
> > major changes from the previous version other than that.
>
> It replaces the dummy task introduced in 0002 by the one that suits our needs
> here (through the new BgTaskWalLevelChange() function).
>
> The design looks reasonable to me. Waiting to see if others disagree before
> looking more closely at the code.

Thanks.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-04-21 17:31:03
Message-ID: CAD21AoAA=zuiajwXgXSCYQWo=6oY-=CGLaEqvpfNUTVsLen+CA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Feb 20, 2025 at 10:05 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Wed, Feb 19, 2025 at 1:56 AM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > Hi,
>
> Thank you for looking at the patches.
>
> >
> > On Mon, Feb 17, 2025 at 12:07:56PM -0800, Masahiko Sawada wrote:
> > > On Fri, Feb 14, 2025 at 2:35 AM Bertrand Drouvot
> > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > Yeap, that was exactly my point when I mentioned the custodian thread (taking
> > > > into account Tom's comment quoted above).
> > > >
> > >
> > > I've written PoC patches to have the online wal_level change work use
> > > a more generic infrastructure. These patches are still in PoC state
> > > but seem like a good direction to me. Here is a brief explanation for
> > > each patch.
> >
> > Thanks for the patches!
> >
> > > * The 0001 patch introduces "reserved background worker slots". We
> > > allocate max_process_workers + BGWORKER_CLASS_RESERVED at startup, and
> > > if the number of running bgworker exceeds max_worker_processes, only
> > > workers using the reserved slots can be launched. We can request to
> > > use the reserved slots by adding BGWORKER_CLASS_RESERVED flag at
> > > bgworker registration.
> >
> > I had a quick look at 0001 and I think the way that's implemented is reasonnable.
> > I thought this could be defined through a GUC so that extensions can benefit
> > from it. But OTOH the core code should ensure the value is > as the number of
> > reserved slots needed by the core so not using a GUC looks ok to me.
>
> Interesting idea. I kept the reserved slots only for internal use but
> it would be worth considering to use GUC instead.
>
> > > * The 0002 patch introduces "bgtask worker". The bgtask infrastructure
> > > is designed to execute internal tasks in background in
> > > one-worker-per-one-task style. Internally, bgtask workers use the
> > > reserved bgworker so it's guaranteed that they can launch.
> >
> > Yeah.
> >
> > > The
> > > internal tasks that we can request are predefined and this patch has a
> > > dummy task as a placeholder. This patch implements only the minimal
> > > functionality for the online wal_level change work. I've not tested if
> > > this bgtask infrastructure can be used for tasks that we wanted to
> > > offload to the custodian worker.
> >
> > Again, I had a quick look and looks simple enough of our need here. It "just"
> > executes "(void) InternalBgTasks[type].func()" and then exists. That's, I think,
> > a good starting point to add more tasks in the future (if we want to).
>
> Yeah, we might want to extend it further, for example to pass an
> argument to the background task or to ask multiple tasks for the
> single bgtask worker. As far as I can read the custodian patch set,
> the work of removing temp files seems not to require any argument
> though.
>
> >
> > > * The 0003 patch makes wal_level a SIGHUP parameter. We do the online
> > > wal_level change work using the bgtask infrastructure. There are no
> > > major changes from the previous version other than that.
> >
> > It replaces the dummy task introduced in 0002 by the one that suits our needs
> > here (through the new BgTaskWalLevelChange() function).
> >
> > The design looks reasonable to me. Waiting to see if others disagree before
> > looking more closely at the code.
>
> Thanks.

I would like to discuss behavioral and user interface considerations.

Upon further analysis of this patch regarding the conversion of
wal_level to a SIGHUP parameter, I find that supporting all
combinations of wal_level value changes might make less sense.
Specifically, changing to or from 'minimal' would necessitate a
checkpoint, and reducing wal_level to 'minimal' would require
terminating physical replication, WAL archiving, and online backups.
While these operations demand careful consideration, there seems to be
no compelling use case for decreasing to 'minimal'. Furthermore,
increasing wal_level from 'minimal' is typically a one-time operation
during a database's lifetime. Therefore, we should weigh the benefits
against the implementation complexity.

One solution is to manage the effective WAL level using two distinct
GUC parameters: max_wal_level and wal_level. max_wal_level would be a
POSTMASTER parameter controlling the system's maximum allowable WAL
level, with values 'minimal', 'replica', and 'logical'. wal_level
would function as a SIGHUP parameter managing the runtime WAL level,
accepting values 'replica', 'logical', and 'auto'. The selected value
must be either 'auto' or not exceed max_wal_level. When set to 'auto',
wal_level automatically synchronizes with max_wal_level's value. This
approach would enable online WAL level transitions between 'replica'
and 'logical'.

Regarding logical decoding on standbys, currently both primary and
standby servers must have wal_level set to 'logical'. We need to
determine the appropriate behavior when users decrease the WAL level
from 'logical' to 'replica' through configuration file reload.

One approach would be to invalidate all logical replication slots on
the standby when transitioning to 'replica' WAL level. Although
incoming WAL records from the primary would still be written at
'logical' level, making logical decoding technically feasible, this
behavior seems logical as it reflects the user's intent to discontinue
logical decoding on the standby. For consistency, we might need to
invalidate logical slots during server startup if the WAL level is
insufficient.

Alternatively, we could permit logical decoding on the standby even
with wal_level set to 'replica'. However, this would necessitate
invalidating all logical replication slots during promotion,
potentially extending downtime during failover.

Regards,

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


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-04-23 12:46:13
Message-ID: CAA4eK1JXZzJKb3RRS4Fsp5d=yseaP9KKmVOMr0bTDWJvbtX+wQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Apr 21, 2025 at 11:01 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> I would like to discuss behavioral and user interface considerations.
>
> Upon further analysis of this patch regarding the conversion of
> wal_level to a SIGHUP parameter, I find that supporting all
> combinations of wal_level value changes might make less sense.
> Specifically, changing to or from 'minimal' would necessitate a
> checkpoint, and reducing wal_level to 'minimal' would require
> terminating physical replication, WAL archiving, and online backups.
> While these operations demand careful consideration, there seems to be
> no compelling use case for decreasing to 'minimal'. Furthermore,
> increasing wal_level from 'minimal' is typically a one-time operation
> during a database's lifetime. Therefore, we should weigh the benefits
> against the implementation complexity.
>
> One solution is to manage the effective WAL level using two distinct
> GUC parameters: max_wal_level and wal_level. max_wal_level would be a
> POSTMASTER parameter controlling the system's maximum allowable WAL
> level, with values 'minimal', 'replica', and 'logical'. wal_level
> would function as a SIGHUP parameter managing the runtime WAL level,
> accepting values 'replica', 'logical', and 'auto'. The selected value
> must be either 'auto' or not exceed max_wal_level. When set to 'auto',
> wal_level automatically synchronizes with max_wal_level's value. This
> approach would enable online WAL level transitions between 'replica'
> and 'logical'.
>
>
> Regarding logical decoding on standbys, currently both primary and
> standby servers must have wal_level set to 'logical'. We need to
> determine the appropriate behavior when users decrease the WAL level
> from 'logical' to 'replica' through configuration file reload.
>
> One approach would be to invalidate all logical replication slots on
> the standby when transitioning to 'replica' WAL level. Although
> incoming WAL records from the primary would still be written at
> 'logical' level, making logical decoding technically feasible, this
> behavior seems logical as it reflects the user's intent to discontinue
> logical decoding on the standby. For consistency, we might need to
> invalidate logical slots during server startup if the WAL level is
> insufficient.
>
> Alternatively, we could permit logical decoding on the standby even
> with wal_level set to 'replica'. However, this would necessitate
> invalidating all logical replication slots during promotion,
> potentially extending downtime during failover.
>

BTW, did we consider the idea to automatically transition to 'logical'
when the first logical slot is created and transition back to
'replica' when last logical slot gets dropped? I see some ideas around
this last time we discussed this topic.

[1] - https://www.postgresql.org/message-id/CAA4eK1J0we5qsZ-ZOwXPbZyvwdWbnT43knO2Cxidia2aHxZSJw%40mail.gmail.com

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-04-23 16:04:20
Message-ID: CAD21AoD4X=9XBRCq5PGPwXA+yZs1GQeXF_ptaqaD1eoJnOjj+g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Mon, Apr 21, 2025 at 11:01 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > I would like to discuss behavioral and user interface considerations.
> >
> > Upon further analysis of this patch regarding the conversion of
> > wal_level to a SIGHUP parameter, I find that supporting all
> > combinations of wal_level value changes might make less sense.
> > Specifically, changing to or from 'minimal' would necessitate a
> > checkpoint, and reducing wal_level to 'minimal' would require
> > terminating physical replication, WAL archiving, and online backups.
> > While these operations demand careful consideration, there seems to be
> > no compelling use case for decreasing to 'minimal'. Furthermore,
> > increasing wal_level from 'minimal' is typically a one-time operation
> > during a database's lifetime. Therefore, we should weigh the benefits
> > against the implementation complexity.
> >
> > One solution is to manage the effective WAL level using two distinct
> > GUC parameters: max_wal_level and wal_level. max_wal_level would be a
> > POSTMASTER parameter controlling the system's maximum allowable WAL
> > level, with values 'minimal', 'replica', and 'logical'. wal_level
> > would function as a SIGHUP parameter managing the runtime WAL level,
> > accepting values 'replica', 'logical', and 'auto'. The selected value
> > must be either 'auto' or not exceed max_wal_level. When set to 'auto',
> > wal_level automatically synchronizes with max_wal_level's value. This
> > approach would enable online WAL level transitions between 'replica'
> > and 'logical'.
> >
> >
> > Regarding logical decoding on standbys, currently both primary and
> > standby servers must have wal_level set to 'logical'. We need to
> > determine the appropriate behavior when users decrease the WAL level
> > from 'logical' to 'replica' through configuration file reload.
> >
> > One approach would be to invalidate all logical replication slots on
> > the standby when transitioning to 'replica' WAL level. Although
> > incoming WAL records from the primary would still be written at
> > 'logical' level, making logical decoding technically feasible, this
> > behavior seems logical as it reflects the user's intent to discontinue
> > logical decoding on the standby. For consistency, we might need to
> > invalidate logical slots during server startup if the WAL level is
> > insufficient.
> >
> > Alternatively, we could permit logical decoding on the standby even
> > with wal_level set to 'replica'. However, this would necessitate
> > invalidating all logical replication slots during promotion,
> > potentially extending downtime during failover.
> >
>
> BTW, did we consider the idea to automatically transition to 'logical'
> when the first logical slot is created and transition back to
> 'replica' when last logical slot gets dropped? I see some ideas around
> this last time we discussed this topic.

Yes. Bertrand pointed out that a drawback is that the primary server
needs to create a logical slot in order to execute logical decoding on
the standbys[1].

Regards,

[1] https://www.postgresql.org/message-id/Z5DCm6xiBfbUdvX7%40ip-10-97-1-34.eu-west-3.compute.internal

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


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-04-24 12:30:07
Message-ID: CAA4eK1JR5aQfhweat_C8hCPGVLhBQczKN-kGLU0XZEDNFD3OXg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 23, 2025 at 9:35 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > BTW, did we consider the idea to automatically transition to 'logical'
> > when the first logical slot is created and transition back to
> > 'replica' when last logical slot gets dropped? I see some ideas around
> > this last time we discussed this topic.
>
> Yes. Bertrand pointed out that a drawback is that the primary server
> needs to create a logical slot in order to execute logical decoding on
> the standbys[1].
>

True, but if we want to avoid that, we can still keep 'logical' as
wal_level for the ease of users. We can also have another API like the
one you originally proposed (pg_activate_logical_decoding) for the
ease of users. But the minimum requirement would be that one creates a
logical slot to enable logical decoding/replication.

Additionally, shall we do some benchmarking, if not done already, to
show the cases where the performance and WAL volume can hurt users if
we make wal_level as 'logical'?

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-04-24 17:44:05
Message-ID: CAD21AoD0+Lw2FW4U_bC18sYuq0AVVdb8JEeW17bt=_dzocSsoQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 24, 2025 at 5:30 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Wed, Apr 23, 2025 at 9:35 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > > BTW, did we consider the idea to automatically transition to 'logical'
> > > when the first logical slot is created and transition back to
> > > 'replica' when last logical slot gets dropped? I see some ideas around
> > > this last time we discussed this topic.
> >
> > Yes. Bertrand pointed out that a drawback is that the primary server
> > needs to create a logical slot in order to execute logical decoding on
> > the standbys[1].
> >
>
> True, but if we want to avoid that, we can still keep 'logical' as
> wal_level for the ease of users.

I think we'd like to cover the use case like where users start with
'replica' on the primary and execute logical decoding on the standby
without neither creating a logical slot on the primary nor restarting
the primary.

> We can also have another API like the
> one you originally proposed (pg_activate_logical_decoding) for the
> ease of users. But the minimum requirement would be that one creates a
> logical slot to enable logical decoding/replication.

I think we want to avoid the runtime WAL level automatically decreased
to 'replica' once all logical slots are removed, if users still want
to execute logical decoding on only the standby. One idea is that if
users enable logical decoding using pg_activate_logical_decoding(),
the runtime WAL level doesn't decrease to 'replica' even if all
logical slots are removed. But it would require for us to remember how
the logical decoding has been enabled in a permanent way. Also, I'm
concerned that having three ways to enable logical decoding could
confuse users: wal_level GUC parameter, creating at least one logical
slot, and pg_activate_logical_decoding().

> Additionally, shall we do some benchmarking, if not done already, to
> show the cases where the performance and WAL volume can hurt users if
> we make wal_level as 'logical'?

I believe it would be significant especially for REPLICA IDENTITY FULL
tables. I agree it's worth benchmarking it but I guess the result
would not convince us to make 'logical' default.

Regards,

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


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-06 07:19:36
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Mon, Apr 21, 2025 at 10:31:03AM -0700, Masahiko Sawada wrote:
> I would like to discuss behavioral and user interface considerations.
>
> Upon further analysis of this patch regarding the conversion of
> wal_level to a SIGHUP parameter, I find that supporting all
> combinations of wal_level value changes might make less sense.
> Specifically, changing to or from 'minimal' would necessitate a
> checkpoint, and reducing wal_level to 'minimal' would require
> terminating physical replication, WAL archiving, and online backups.
> While these operations demand careful consideration, there seems to be
> no compelling use case for decreasing to 'minimal'. Furthermore,
> increasing wal_level from 'minimal' is typically a one-time operation
> during a database's lifetime. Therefore, we should weigh the benefits
> against the implementation complexity.

Agree.

> One solution is to manage the effective WAL level using two distinct
> GUC parameters: max_wal_level and wal_level. max_wal_level would be a
> POSTMASTER parameter controlling the system's maximum allowable WAL
> level, with values 'minimal', 'replica', and 'logical'. wal_level
> would function as a SIGHUP parameter managing the runtime WAL level,
> accepting values 'replica', 'logical', and 'auto'. The selected value
> must be either 'auto' or not exceed max_wal_level. When set to 'auto',
> wal_level automatically synchronizes with max_wal_level's value. This
> approach would enable online WAL level transitions between 'replica'
> and 'logical'.

That makes sense to me. I think that 'logical' could be the default value
for max_wal_level and 'replica' the default for wal_level.
I think that would provide almost the same user experience as currently and would
allow replica->logical change without restart. Thoughts?

> Regarding logical decoding on standbys, currently both primary and
> standby servers must have wal_level set to 'logical'. We need to
> determine the appropriate behavior when users decrease the WAL level
> from 'logical' to 'replica' through configuration file reload.
>
> One approach would be to invalidate all logical replication slots on
> the standby when transitioning to 'replica' WAL level. Although
> incoming WAL records from the primary would still be written at
> 'logical' level, making logical decoding technically feasible, this
> behavior seems logical as it reflects the user's intent to discontinue
> logical decoding on the standby.

+1

> For consistency, we might need to
> invalidate logical slots during server startup if the WAL level is
> insufficient.

Not sure. Currently we'd not allow the standby to start:

"
LOG: entering standby mode
FATAL: logical replication slot "logical_slot" exists, but "wal_level" < "logical"
HINT: Change "wal_level" to be "logical" or higher.
LOG: startup process (PID 1790508) exited with exit code 1
"

I think that's a good guard for configuration change mistakes. If that's a mistake
change back to logical and start. If that's not a mistake then change back to
logical, start, change with SIGHUP. OTOH I also see the benefits of being consistent
between SIGHUP and start.

> Alternatively, we could permit logical decoding on the standby even
> with wal_level set to 'replica'.

Yeah, technically speaking we could as the WALs are coming from the primary (that
has wal_level set to logical).

> However, this would necessitate
> invalidating all logical replication slots during promotion,
> potentially extending downtime during failover.

Yeah, I'm tempted to vote to not allow logical decoding on the standby if the
wal_level is not logical.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-07 06:59:10
Message-ID: CAA4eK1JzAt+v-M4E_BVnAo9fJTinGLGOGjAdmJXnGKrOdFdfog@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 24, 2025 at 11:14 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Apr 24, 2025 at 5:30 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > On Wed, Apr 23, 2025 at 9:35 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > >
> > > > BTW, did we consider the idea to automatically transition to 'logical'
> > > > when the first logical slot is created and transition back to
> > > > 'replica' when last logical slot gets dropped? I see some ideas around
> > > > this last time we discussed this topic.
> > >
> > > Yes. Bertrand pointed out that a drawback is that the primary server
> > > needs to create a logical slot in order to execute logical decoding on
> > > the standbys[1].
> > >
> >
> > True, but if we want to avoid that, we can still keep 'logical' as
> > wal_level for the ease of users.
>
> I think we'd like to cover the use case like where users start with
> 'replica' on the primary and execute logical decoding on the standby
> without neither creating a logical slot on the primary nor restarting
> the primary.
>

Okay, if we introduce a SIGHUP GUC like max_wal_level as you are
proposing, the above requirement will be fulfilled, right? The other
way is by API pg_activate_logical_decoding().

> > We can also have another API like the
> > one you originally proposed (pg_activate_logical_decoding) for the
> > ease of users. But the minimum requirement would be that one creates a
> > logical slot to enable logical decoding/replication.
>
> I think we want to avoid the runtime WAL level automatically decreased
> to 'replica' once all logical slots are removed, if users still want
> to execute logical decoding on only the standby. One idea is that if
> users enable logical decoding using pg_activate_logical_decoding(),
> the runtime WAL level doesn't decrease to 'replica' even if all
> logical slots are removed.
>

That makes sense. If we are using an API like
pg_activate_*/pg_deactivate_*, then why add an additional dependency
on the slots?

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-07 16:31:42
Message-ID: CAD21AoD1X6zcyS3i+2oLDro6ny6yDxn-K9MUA8ntAgEUSLfxYA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, May 6, 2025 at 12:19 AM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Mon, Apr 21, 2025 at 10:31:03AM -0700, Masahiko Sawada wrote:
> > I would like to discuss behavioral and user interface considerations.
> >
> > Upon further analysis of this patch regarding the conversion of
> > wal_level to a SIGHUP parameter, I find that supporting all
> > combinations of wal_level value changes might make less sense.
> > Specifically, changing to or from 'minimal' would necessitate a
> > checkpoint, and reducing wal_level to 'minimal' would require
> > terminating physical replication, WAL archiving, and online backups.
> > While these operations demand careful consideration, there seems to be
> > no compelling use case for decreasing to 'minimal'. Furthermore,
> > increasing wal_level from 'minimal' is typically a one-time operation
> > during a database's lifetime. Therefore, we should weigh the benefits
> > against the implementation complexity.
>
> Agree.
>
> > One solution is to manage the effective WAL level using two distinct
> > GUC parameters: max_wal_level and wal_level. max_wal_level would be a
> > POSTMASTER parameter controlling the system's maximum allowable WAL
> > level, with values 'minimal', 'replica', and 'logical'. wal_level
> > would function as a SIGHUP parameter managing the runtime WAL level,
> > accepting values 'replica', 'logical', and 'auto'. The selected value
> > must be either 'auto' or not exceed max_wal_level. When set to 'auto',
> > wal_level automatically synchronizes with max_wal_level's value. This
> > approach would enable online WAL level transitions between 'replica'
> > and 'logical'.
>
> That makes sense to me. I think that 'logical' could be the default value
> for max_wal_level and 'replica' the default for wal_level.
> I think that would provide almost the same user experience as currently and would
> allow replica->logical change without restart. Thoughts?

Sounds reasonable default values. One thing we might want to note is
that when users want to set 'minimal', they would need to change both
parameters. With the defaults value wal_level='auto', users would need
to simply set max_wal_level='minimal'. However, given that it's more
common for users to start with 'replica' than 'minimal', probably it
would make sense to have the default values you suggested. This
combination of WAL levels maximize the benefit of this idea while
maintaining the default behavior.

One downside of this idea is that we introduce another GUC parameter,
resulting in that users would need to control WAL level using two
parameters, which might not be quite clear for users.

>
> > Regarding logical decoding on standbys, currently both primary and
> > standby servers must have wal_level set to 'logical'. We need to
> > determine the appropriate behavior when users decrease the WAL level
> > from 'logical' to 'replica' through configuration file reload.
> >
> > One approach would be to invalidate all logical replication slots on
> > the standby when transitioning to 'replica' WAL level. Although
> > incoming WAL records from the primary would still be written at
> > 'logical' level, making logical decoding technically feasible, this
> > behavior seems logical as it reflects the user's intent to discontinue
> > logical decoding on the standby.
>
> +1
>
> > For consistency, we might need to
> > invalidate logical slots during server startup if the WAL level is
> > insufficient.
>
> Not sure. Currently we'd not allow the standby to start:
>
> "
> LOG: entering standby mode
> FATAL: logical replication slot "logical_slot" exists, but "wal_level" < "logical"
> HINT: Change "wal_level" to be "logical" or higher.
> LOG: startup process (PID 1790508) exited with exit code 1
> "
>
> I think that's a good guard for configuration change mistakes. If that's a mistake
> change back to logical and start. If that's not a mistake then change back to
> logical, start, change with SIGHUP. OTOH I also see the benefits of being consistent
> between SIGHUP and start.

I see your point.

An alternative idea would be to somehow prevent wal_level from being
changed to 'replica' while there is at least one active logical slot
on the standby. I'll consider this idea too.

Regards,

--
Masahiko Sawada

Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-07 19:35:33
Message-ID: CAD21AoAvuM-cY-AcoMVLarzXUoAL+QHXWo1euq=AhYb0JMfBBA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, May 6, 2025 at 11:59 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Thu, Apr 24, 2025 at 11:14 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Thu, Apr 24, 2025 at 5:30 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Apr 23, 2025 at 9:35 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > >
> > > > > BTW, did we consider the idea to automatically transition to 'logical'
> > > > > when the first logical slot is created and transition back to
> > > > > 'replica' when last logical slot gets dropped? I see some ideas around
> > > > > this last time we discussed this topic.
> > > >
> > > > Yes. Bertrand pointed out that a drawback is that the primary server
> > > > needs to create a logical slot in order to execute logical decoding on
> > > > the standbys[1].
> > > >
> > >
> > > True, but if we want to avoid that, we can still keep 'logical' as
> > > wal_level for the ease of users.
> >
> > I think we'd like to cover the use case like where users start with
> > 'replica' on the primary and execute logical decoding on the standby
> > without neither creating a logical slot on the primary nor restarting
> > the primary.
> >
>
> Okay, if we introduce a SIGHUP GUC like max_wal_level as you are
> proposing, the above requirement will be fulfilled, right?

Right. Both the primary and the standby can increase WAL level to
'logical' without server restart nor creating a logical slot.

> The other
> way is by API pg_activate_logical_decoding().

Yes. This approach would be simpler than the current proposal as we
don't need other new infrastructure such as executing a task in the
background. However, we might want to note that wal_level value would
no longer show the actual runtime WAL level if the logical decoding is
activated via this API. Probably it's better to introduce a read-only
GUC, say runtime_wal_level, showing the actual WAL level. Also,
Ashutosh pointed out[1] before that cloud providers do not like
multiple ways of changing configuration esp. when they can not control
it. But I'm not sure this applies to the API as it's a SQL function
whose access privilege can be controlled.

>
> > > We can also have another API like the
> > > one you originally proposed (pg_activate_logical_decoding) for the
> > > ease of users. But the minimum requirement would be that one creates a
> > > logical slot to enable logical decoding/replication.
> >
> > I think we want to avoid the runtime WAL level automatically decreased
> > to 'replica' once all logical slots are removed, if users still want
> > to execute logical decoding on only the standby. One idea is that if
> > users enable logical decoding using pg_activate_logical_decoding(),
> > the runtime WAL level doesn't decrease to 'replica' even if all
> > logical slots are removed.
> >
>
> That makes sense. If we are using an API like
> pg_activate_*/pg_deactivate_*, then why add an additional dependency
> on the slots?

I thought that we need to remember how logical decoding got enabled
because otherwise even if we enable logical decoding using the API,
it's disabled to 'replica' if all logical slots get removed. So the
idea I mentioned above is that we somehow prevent logical decoding
from being disabled even if all logical slots are removed. If we're
using only these APIs to enable/disable logical decoding, we don't
need to add a dependency on the slots, although we probably want to
disallow disabling logical decoding if there is at least one active
logical slot.

Regards,

[1] https://www.postgresql.org/message-id/CAExHW5tyJrdjqKFQ%2BqDs8Yq3E_P1Fj_T4pwVW9WACmMznRtDuw%40mail.gmail.com

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


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-10 07:00:39
Message-ID: CAA4eK1K8Ji9sE8otCvX1OjLPPea-yX-7r4+pOTbY5w7hAFawmw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, May 8, 2025 at 1:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Tue, May 6, 2025 at 11:59 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > On Thu, Apr 24, 2025 at 11:14 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Thu, Apr 24, 2025 at 5:30 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Apr 23, 2025 at 9:35 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > BTW, did we consider the idea to automatically transition to 'logical'
> > > > > > when the first logical slot is created and transition back to
> > > > > > 'replica' when last logical slot gets dropped? I see some ideas around
> > > > > > this last time we discussed this topic.
> > > > >
> > > > > Yes. Bertrand pointed out that a drawback is that the primary server
> > > > > needs to create a logical slot in order to execute logical decoding on
> > > > > the standbys[1].
> > > > >
> > > >
> > > > True, but if we want to avoid that, we can still keep 'logical' as
> > > > wal_level for the ease of users.
> > >
> > > I think we'd like to cover the use case like where users start with
> > > 'replica' on the primary and execute logical decoding on the standby
> > > without neither creating a logical slot on the primary nor restarting
> > > the primary.
> > >
> >
> > Okay, if we introduce a SIGHUP GUC like max_wal_level as you are
> > proposing, the above requirement will be fulfilled, right?
>
> Right. Both the primary and the standby can increase WAL level to
> 'logical' without server restart nor creating a logical slot.
>
> > The other
> > way is by API pg_activate_logical_decoding().
>
> Yes. This approach would be simpler than the current proposal as we
> don't need other new infrastructure such as executing a task in the
> background.
>

Right, but to an extent, this is also similar to having a requirement
of a logical slot on the primary. Now, it seems to me that the point
you are trying to make is that to allow logical decoding on standby,
it is okay to ask users to use pg_activate_logical_decoding() on
primary, but it would be inconvenient to ask them to have a logical
slot on primary instead. If my understanding is correct, then why do
you think so? We recommend that users have a physical slot on primary
and use it via primary_slot_name on standby to control resource
removal, so why can't we ask them to have a logical slot on primary to
allow logical decoding on standby?

> However, we might want to note that wal_level value would
> no longer show the actual runtime WAL level if the logical decoding is
> activated via this API. Probably it's better to introduce a read-only
> GUC, say runtime_wal_level, showing the actual WAL level.
>

Yeah, we need some way to show the correct value. In one of the
previous emails on this thread, you mentioned that we can use
show_hook to show the correct value. I see that show_in_hot_standby()
uses in_memory value to show the correct value. Do you have something
like that in your mind?

BTW, what is your idea to preserve the state to allow logical decoding
across server restart when the user uses the API, do we want to
persist the state in some way, if so, how? OTOH, if we use the idea to
have a logical slot to allow decoding, then the presence of a logical
slot can tell us whether we need to enable the new state to allow
logical decoding after restart.

> Also,
> Ashutosh pointed out[1] before that cloud providers do not like
> multiple ways of changing configuration esp. when they can not control
> it. But I'm not sure this applies to the API as it's a SQL function
> whose access privilege can be controlled.
>

By multiple ways, do we mean to say that one way for users would be to
use the existing way (change wal_level to logical and restart server),
and the other way would be to use the new API (or have a logical
slot)? But won't similarly users have multiple ways to retain WAL for
standby servers (either by using wal_keep_size or by having a
primary_slot_name). The other example is that one can either manually
change postgresql.conf file or use ALTER SYSTEM to change it, and then
reloadthe config or restart the server for the change to take effect.
There could be other similar examples as well if one tries to list all
such possibilities. I feel one should be concerned if we are trying to
make both wal_level GUC as SIGHUP, and also try to provide an API to
enable logical decoding.

> > >
> >
> > That makes sense. If we are using an API like
> > pg_activate_*/pg_deactivate_*, then why add an additional dependency
> > on the slots?
>
> I thought that we need to remember how logical decoding got enabled
> because otherwise even if we enable logical decoding using the API,
> it's disabled to 'replica' if all logical slots get removed. So the
> idea I mentioned above is that we somehow prevent logical decoding
> from being disabled even if all logical slots are removed. If we're
> using only these APIs to enable/disable logical decoding, we don't
> need to add a dependency on the slots, although we probably want to
> disallow disabling logical decoding if there is at least one active
> logical slot.
>

Yeah, this is a detail that should be discussed once we finalize the
API to enable logical decoding on both primary and standby without
restarting the primary server.

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-10 07:35:15
Message-ID: CAD21AoCYHqsKBw8mSTA6ZO5ODuaiHEUUnjk4-i18inLU702yEw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sat, May 10, 2025 at 12:00 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Thu, May 8, 2025 at 1:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Tue, May 6, 2025 at 11:59 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > > On Thu, Apr 24, 2025 at 11:14 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Thu, Apr 24, 2025 at 5:30 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Wed, Apr 23, 2025 at 9:35 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > On Wed, Apr 23, 2025 at 5:46 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > > > >
> > > > > > > BTW, did we consider the idea to automatically transition to 'logical'
> > > > > > > when the first logical slot is created and transition back to
> > > > > > > 'replica' when last logical slot gets dropped? I see some ideas around
> > > > > > > this last time we discussed this topic.
> > > > > >
> > > > > > Yes. Bertrand pointed out that a drawback is that the primary server
> > > > > > needs to create a logical slot in order to execute logical decoding on
> > > > > > the standbys[1].
> > > > > >
> > > > >
> > > > > True, but if we want to avoid that, we can still keep 'logical' as
> > > > > wal_level for the ease of users.
> > > >
> > > > I think we'd like to cover the use case like where users start with
> > > > 'replica' on the primary and execute logical decoding on the standby
> > > > without neither creating a logical slot on the primary nor restarting
> > > > the primary.
> > > >
> > >
> > > Okay, if we introduce a SIGHUP GUC like max_wal_level as you are
> > > proposing, the above requirement will be fulfilled, right?
> >
> > Right. Both the primary and the standby can increase WAL level to
> > 'logical' without server restart nor creating a logical slot.
> >
> > > The other
> > > way is by API pg_activate_logical_decoding().
> >
> > Yes. This approach would be simpler than the current proposal as we
> > don't need other new infrastructure such as executing a task in the
> > background.
> >
>
> Right, but to an extent, this is also similar to having a requirement
> of a logical slot on the primary. Now, it seems to me that the point
> you are trying to make is that to allow logical decoding on standby,
> it is okay to ask users to use pg_activate_logical_decoding() on
> primary, but it would be inconvenient to ask them to have a logical
> slot on primary instead. If my understanding is correct, then why do
> you think so? We recommend that users have a physical slot on primary
> and use it via primary_slot_name on standby to control resource
> removal, so why can't we ask them to have a logical slot on primary to
> allow logical decoding on standby?

I was thinking of a simple use case where users do logical decoding
from the physical standby. That is, the primary has a physical slot
and the standby uses it via primary_slot_name, and the subscriber
connects the standby server for logical replication with a logical
slot on the standby. In this case, IIUC we need to require users to
create a logical slot on the primary in order just to increase WAL
level to 'logical', but it doesn't make sense to me. No one is going
to use this logical slot and the primary ends up accumulating WALs.

> > However, we might want to note that wal_level value would
> > no longer show the actual runtime WAL level if the logical decoding is
> > activated via this API. Probably it's better to introduce a read-only
> > GUC, say runtime_wal_level, showing the actual WAL level.
> >
>
> Yeah, we need some way to show the correct value. In one of the
> previous emails on this thread, you mentioned that we can use
> show_hook to show the correct value. I see that show_in_hot_standby()
> uses in_memory value to show the correct value. Do you have something
> like that in your mind?

Yes.

> BTW, what is your idea to preserve the state to allow logical decoding
> across server restart when the user uses the API, do we want to
> persist the state in some way, if so, how? OTOH, if we use the idea to
> have a logical slot to allow decoding, then the presence of a logical
> slot can tell us whether we need to enable the new state to allow
> logical decoding after restart.

I vaguely thought of storing such information in the control file or a
checkpoint record along with wal_level value. But I've not seriously
considered how to implement this idea as I don't think it's not a good
user interface.

>
> > Also,
> > Ashutosh pointed out[1] before that cloud providers do not like
> > multiple ways of changing configuration esp. when they can not control
> > it. But I'm not sure this applies to the API as it's a SQL function
> > whose access privilege can be controlled.
> >
>
> By multiple ways, do we mean to say that one way for users would be to
> use the existing way (change wal_level to logical and restart server),
> and the other way would be to use the new API (or have a logical
> slot)?

Yes, that's my understanding of his comment.

> But won't similarly users have multiple ways to retain WAL for
> standby servers (either by using wal_keep_size or by having a
> primary_slot_name). The other example is that one can either manually
> change postgresql.conf file or use ALTER SYSTEM to change it, and then
> reloadthe config or restart the server for the change to take effect.
> There could be other similar examples as well if one tries to list all
> such possibilities.

True. I think allow_alter_system was introduced for users who don't
want to let their end users change the configuration via ALTER SYSTEM
command. Since the new API we're considering is an SQL function we
already have a way to control its access for such users.

> I feel one should be concerned if we are trying to
> make both wal_level GUC as SIGHUP, and also try to provide an API to
> enable logical decoding.

Agreed.

>
> > > >
> > >
> > > That makes sense. If we are using an API like
> > > pg_activate_*/pg_deactivate_*, then why add an additional dependency
> > > on the slots?
> >
> > I thought that we need to remember how logical decoding got enabled
> > because otherwise even if we enable logical decoding using the API,
> > it's disabled to 'replica' if all logical slots get removed. So the
> > idea I mentioned above is that we somehow prevent logical decoding
> > from being disabled even if all logical slots are removed. If we're
> > using only these APIs to enable/disable logical decoding, we don't
> > need to add a dependency on the slots, although we probably want to
> > disallow disabling logical decoding if there is at least one active
> > logical slot.
> >
>
> Yeah, this is a detail that should be discussed once we finalize the
> API to enable logical decoding on both primary and standby without
> restarting the primary server.

Agreed.

Another approach we might need to consider is to convert wal_level to
a SIGHUP parameter. While I mentioned that supporting all combinations
of wal_level value changes might make less sense for its complexity, I
think this is the most straightforward approach and interface. So it
might be worth trying to implement this approach to figure out the
actual complexity.

Regards,

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


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-10 11:08:03
Message-ID: CAA4eK1LY-PD28hfi0-3ZxzOg=MDSNs=8zXminCJ-GXgrqhwR0w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sat, May 10, 2025 at 1:05 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Sat, May 10, 2025 at 12:00 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> >
> > Right, but to an extent, this is also similar to having a requirement
> > of a logical slot on the primary. Now, it seems to me that the point
> > you are trying to make is that to allow logical decoding on standby,
> > it is okay to ask users to use pg_activate_logical_decoding() on
> > primary, but it would be inconvenient to ask them to have a logical
> > slot on primary instead. If my understanding is correct, then why do
> > you think so? We recommend that users have a physical slot on primary
> > and use it via primary_slot_name on standby to control resource
> > removal, so why can't we ask them to have a logical slot on primary to
> > allow logical decoding on standby?
>
> I was thinking of a simple use case where users do logical decoding
> from the physical standby. That is, the primary has a physical slot
> and the standby uses it via primary_slot_name, and the subscriber
> connects the standby server for logical replication with a logical
> slot on the standby. In this case, IIUC we need to require users to
> create a logical slot on the primary in order just to increase WAL
> level to 'logical', but it doesn't make sense to me. No one is going
> to use this logical slot and the primary ends up accumulating WALs.
>

Can we have a parameter like immediately_reserve in
create_logical_slot API, similar to what we have for physical slots?
We need to work out the details, but that should address the kind of
use case you are worried about, unless I am missing something.

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-17 19:38:36
Message-ID: CAD21AoB5T5hxniyCQ4VVscrNAAvfFaK12TX3Aiqth=87qhEzeQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sat, May 10, 2025 at 7:08 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Sat, May 10, 2025 at 1:05 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Sat, May 10, 2025 at 12:00 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > >
> > > Right, but to an extent, this is also similar to having a requirement
> > > of a logical slot on the primary. Now, it seems to me that the point
> > > you are trying to make is that to allow logical decoding on standby,
> > > it is okay to ask users to use pg_activate_logical_decoding() on
> > > primary, but it would be inconvenient to ask them to have a logical
> > > slot on primary instead. If my understanding is correct, then why do
> > > you think so? We recommend that users have a physical slot on primary
> > > and use it via primary_slot_name on standby to control resource
> > > removal, so why can't we ask them to have a logical slot on primary to
> > > allow logical decoding on standby?
> >
> > I was thinking of a simple use case where users do logical decoding
> > from the physical standby. That is, the primary has a physical slot
> > and the standby uses it via primary_slot_name, and the subscriber
> > connects the standby server for logical replication with a logical
> > slot on the standby. In this case, IIUC we need to require users to
> > create a logical slot on the primary in order just to increase WAL
> > level to 'logical', but it doesn't make sense to me. No one is going
> > to use this logical slot and the primary ends up accumulating WALs.
> >
>
> Can we have a parameter like immediately_reserve in
> create_logical_slot API, similar to what we have for physical slots?
> We need to work out the details, but that should address the kind of
> use case you are worried about, unless I am missing something.

Interesting idea. One concern in my mind is that in the use case I
mentioned above, users would need to carefully manage the extra
logical slot to keep the logical decoding active. The logical decoding
is deactivated on the standby as soon as users drop all logical slots
on the primary.

Also, with this idea of automatically increasing WAL level, do we want
to keep the 'logical' WAL level? If so, it requires an extra step of
creating a non-reserved logical slot on the primary in order for the
standby to activate the logical decoding. On the other hand, we can
also keep the 'logical' WAL level for the compatibility and for making
the logical decoding enabled without the coordination of WAL level
transition. But wal_level GUC parameter would no longer tell the
actual WAL level to users when 'replica' + logical slots. Is it
sufficient to provide a read-only GUC parameter, say
effective_wal_level showing the actual WAL level being used?

Regards,

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


From: Dilip Kumar <dilipbalaut(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-18 10:36:31
Message-ID: CAFiTN-u-n03Q6neBosX_7Y7+1pvA8spbbVou4_t4O_rGtmFKhQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, May 18, 2025 at 1:09 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Sat, May 10, 2025 at 7:08 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > On Sat, May 10, 2025 at 1:05 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Sat, May 10, 2025 at 12:00 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > >
> > > >
> > > > Right, but to an extent, this is also similar to having a requirement
> > > > of a logical slot on the primary. Now, it seems to me that the point
> > > > you are trying to make is that to allow logical decoding on standby,
> > > > it is okay to ask users to use pg_activate_logical_decoding() on
> > > > primary, but it would be inconvenient to ask them to have a logical
> > > > slot on primary instead. If my understanding is correct, then why do
> > > > you think so? We recommend that users have a physical slot on primary
> > > > and use it via primary_slot_name on standby to control resource
> > > > removal, so why can't we ask them to have a logical slot on primary to
> > > > allow logical decoding on standby?
> > >
> > > I was thinking of a simple use case where users do logical decoding
> > > from the physical standby. That is, the primary has a physical slot
> > > and the standby uses it via primary_slot_name, and the subscriber
> > > connects the standby server for logical replication with a logical
> > > slot on the standby. In this case, IIUC we need to require users to
> > > create a logical slot on the primary in order just to increase WAL
> > > level to 'logical', but it doesn't make sense to me. No one is going
> > > to use this logical slot and the primary ends up accumulating WALs.
> > >
> >
> > Can we have a parameter like immediately_reserve in
> > create_logical_slot API, similar to what we have for physical slots?
> > We need to work out the details, but that should address the kind of
> > use case you are worried about, unless I am missing something.
>
> Interesting idea. One concern in my mind is that in the use case I
> mentioned above, users would need to carefully manage the extra
> logical slot to keep the logical decoding active. The logical decoding
> is deactivated on the standby as soon as users drop all logical slots
> on the primary.
>
> Also, with this idea of automatically increasing WAL level, do we want
> to keep the 'logical' WAL level? If so, it requires an extra step of
> creating a non-reserved logical slot on the primary in order for the
> standby to activate the logical decoding. On the other hand, we can
> also keep the 'logical' WAL level for the compatibility and for making
> the logical decoding enabled without the coordination of WAL level
> transition. But wal_level GUC parameter would no longer tell the
> actual WAL level to users when 'replica' + logical slots. Is it
> sufficient to provide a read-only GUC parameter, say
> effective_wal_level showing the actual WAL level being used?
>

Thanks for proposing the idea of making wal_level configurable at
runtime. But why isn't making the relevant GUCs SIGHUP-reloadable
sufficient?

For enabling logical replication, users are already familiar with the
wal_level and max_wal_senders settings. The main issue is that
changing them currently requires a server restart. If we can address
that by making the GUCs reloadable via SIGHUP, that might be enough.

On the other hand, if the goal is to make the behavior fully dynamic,
then we should go all the way, decouple it from wal_level. For
example, we could start logging the extra WAL needed for logical
decoding as soon as a logical slot is created, and stop once all
logical slots are dropped, even if wal_level is still set to logical.

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-19 09:05:08
Message-ID: CAA4eK1K+Ao2YWD9NxRUKm4c928P_VLUifKwNgV13CdShsK42fA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, May 18, 2025 at 1:09 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Sat, May 10, 2025 at 7:08 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> >
> > Can we have a parameter like immediately_reserve in
> > create_logical_slot API, similar to what we have for physical slots?
> > We need to work out the details, but that should address the kind of
> > use case you are worried about, unless I am missing something.
>
> Interesting idea. One concern in my mind is that in the use case I
> mentioned above, users would need to carefully manage the extra
> logical slot to keep the logical decoding active. The logical decoding
> is deactivated on the standby as soon as users drop all logical slots
> on the primary.
>

Yes, but the same is true for a physical slot in the case of physical
replication used via primary_slot_name parameter.

> Also, with this idea of automatically increasing WAL level, do we want
> to keep the 'logical' WAL level? If so, it requires an extra step of
> creating a non-reserved logical slot on the primary in order for the
> standby to activate the logical decoding. On the other hand, we can
> also keep the 'logical' WAL level for the compatibility and for making
> the logical decoding enabled without the coordination of WAL level
> transition.

Right, I also feel we should retain both ways to enable logical
replication at least initially. Once we get some feedback, we may
think of removing 'logical' as wal_level.

> But wal_level GUC parameter would no longer tell the
> actual WAL level to users when 'replica' + logical slots.
>

Right.

> Is it
> sufficient to provide a read-only GUC parameter, say
> effective_wal_level showing the actual WAL level being used?
>

I am not so sure about how we want to communicate this to the user,
but I guess to start with, this is a good idea.

--
With Regards,
Amit Kapila.


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Dilip Kumar <dilipbalaut(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-19 09:15:56
Message-ID: CAA4eK1LkdHUDWQuVZh77cbw-0UYg62BKoTqefhHoYVRHVqMxMw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, May 18, 2025 at 4:06 PM Dilip Kumar <dilipbalaut(at)gmail(dot)com> wrote:
>
> Thanks for proposing the idea of making wal_level configurable at
> runtime. But why isn't making the relevant GUCs SIGHUP-reloadable
> sufficient?
>
> For enabling logical replication, users are already familiar with the
> wal_level and max_wal_senders settings. The main issue is that
> changing them currently requires a server restart. If we can address
> that by making the GUCs reloadable via SIGHUP, that might be enough.
>

Sure, but the challenges are huge. Consider cases like one wants to
change wal_level from 'logical' to 'minimal'. See some analysis of the
same in email [1]. I think it will be a much bigger and challenging
project with diminishing returns as compared to the alternative we are
discussing.

> On the other hand, if the goal is to make the behavior fully dynamic,
> then we should go all the way, decouple it from wal_level. For
> example, we could start logging the extra WAL needed for logical
> decoding as soon as a logical slot is created, and stop once all
> logical slots are dropped, even if wal_level is still set to logical.
>

Yeah, this is one thing that is still under consideration. It is
almost equivalent to removing wal_level as 'logical', which sounds
like a compatibility break, and even if we want to do that, it is
better to attempt that after the base version is committed and we get
a broader consensus on the same.

[1]- https://www.postgresql.org/message-id/CAD21AoAA%3DzuiajwXgXSCYQWo%3D6oY-%3DCGLaEqvpfNUTVsLen%2BCA%40mail.gmail.com

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-20 19:14:49
Message-ID: CAD21AoB0b8=vJYhpPq7xXC+Y64t+dzBX53PpPwSOtPL7bNHD=w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, May 19, 2025 at 2:05 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Sun, May 18, 2025 at 1:09 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Sat, May 10, 2025 at 7:08 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > >
> > > Can we have a parameter like immediately_reserve in
> > > create_logical_slot API, similar to what we have for physical slots?
> > > We need to work out the details, but that should address the kind of
> > > use case you are worried about, unless I am missing something.
> >
> > Interesting idea. One concern in my mind is that in the use case I
> > mentioned above, users would need to carefully manage the extra
> > logical slot to keep the logical decoding active. The logical decoding
> > is deactivated on the standby as soon as users drop all logical slots
> > on the primary.
> >
>
> Yes, but the same is true for a physical slot in the case of physical
> replication used via primary_slot_name parameter.

Could you elaborate on this? IIUC the purpose of using a physical slot
in a physical replication case is obvious; users don't want to lose
WAL files necessary for replication. On the other hand, this empty
logical slot needs to be maintained just for keeping the logical
decoding active.

>
> > Also, with this idea of automatically increasing WAL level, do we want
> > to keep the 'logical' WAL level? If so, it requires an extra step of
> > creating a non-reserved logical slot on the primary in order for the
> > standby to activate the logical decoding. On the other hand, we can
> > also keep the 'logical' WAL level for the compatibility and for making
> > the logical decoding enabled without the coordination of WAL level
> > transition.
>
> Right, I also feel we should retain both ways to enable logical
> replication at least initially. Once we get some feedback, we may
> think of removing 'logical' as wal_level.
>
> > But wal_level GUC parameter would no longer tell the
> > actual WAL level to users when 'replica' + logical slots.
> >
>
> Right.
>
> > Is it
> > sufficient to provide a read-only GUC parameter, say
> > effective_wal_level showing the actual WAL level being used?
> >
>
> I am not so sure about how we want to communicate this to the user,
> but I guess to start with, this is a good idea.

I recently had a discussion with Ashtosh at PGConf.dev regarding an
alternative approach: introducing a new command syntax such as "ALTER
SYSTEM UPDATE wal_level TO 'logical'". In his presentation[1], he
outlined this proposed command as a means to modify specific GUC
parameters synchronously. The backend executing this command would
manage the transition, allowing users to interrupt the process via
Ctrl-C if necessary. In the specific context of wal_level change, this
command could be designed to reject operations like "ALTER SYSTEM
UPDATE wal_level TO 'minimal'" with an error, effectively preventing
undesirable wal_level transitions to or from 'minimal'. While this
approach shares similarities with our previous proposal of
implementing a dedicated SQL function for WAL level modifications, it
offers a more standardized interface for users.

Though I find merit in this proposal, I remain uncertain about its
implementation details and whether it represents the optimal solution
for online wal_level changes, particularly given that our current
approach of automatic WAL level adjustment appears viable. Ashtosh
plans to initiate a separate discussion thread where we can explore
these considerations in greater detail.

Regards,

[1] https://www.pgevents.ca/events/pgconfdev2025/schedule/session/286-changing-shared_buffers-on-the-fly/

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


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-05-21 04:54:41
Message-ID: CAA4eK1+EctVndhKkcWRA-eLpE5izCD5Ff=FjdqXq6bGUr53QHg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, May 21, 2025 at 12:45 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Mon, May 19, 2025 at 2:05 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > On Sun, May 18, 2025 at 1:09 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Sat, May 10, 2025 at 7:08 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > >
> > > >
> > > > Can we have a parameter like immediately_reserve in
> > > > create_logical_slot API, similar to what we have for physical slots?
> > > > We need to work out the details, but that should address the kind of
> > > > use case you are worried about, unless I am missing something.
> > >
> > > Interesting idea. One concern in my mind is that in the use case I
> > > mentioned above, users would need to carefully manage the extra
> > > logical slot to keep the logical decoding active. The logical decoding
> > > is deactivated on the standby as soon as users drop all logical slots
> > > on the primary.
> > >
> >
> > Yes, but the same is true for a physical slot in the case of physical
> > replication used via primary_slot_name parameter.
>
> Could you elaborate on this?
>

I am trying to correlate with the case where standby no longer needs
physical slot due to some reason like the standby machine failure, or
say someone uses pg_createsubscriber on standby to make it subscriber,
etc. In such a case, user needs to manually remove the physical slot
on primary. There is difference in both cases but the point is one may
need to manage physical slot as well.

>
> I recently had a discussion with Ashtosh at PGConf.dev regarding an
> alternative approach: introducing a new command syntax such as "ALTER
> SYSTEM UPDATE wal_level TO 'logical'". In his presentation[1], he
> outlined this proposed command as a means to modify specific GUC
> parameters synchronously. The backend executing this command would
> manage the transition, allowing users to interrupt the process via
> Ctrl-C if necessary. In the specific context of wal_level change, this
> command could be designed to reject operations like "ALTER SYSTEM
> UPDATE wal_level TO 'minimal'" with an error, effectively preventing
> undesirable wal_level transitions to or from 'minimal'. While this
> approach shares similarities with our previous proposal of
> implementing a dedicated SQL function for WAL level modifications, it
> offers a more standardized interface for users.
>
> Though I find merit in this proposal, I remain uncertain about its
> implementation details and whether it represents the optimal solution
> for online wal_level changes, particularly given that our current
> approach of automatic WAL level adjustment appears viable.
>

Yeah, I find the idea that the presence of a logical slot will allow
the user to enable logical decoding/replication more appealing than
this new alternative, leaving aside the challenges of realizing it.

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-04 01:10:44
Message-ID: CAD21AoBRD5zmh8D3HW3u=O7EwWJYc8ozik5Tje4Yi2RYe3iCzg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, May 20, 2025 at 9:54 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Wed, May 21, 2025 at 12:45 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Mon, May 19, 2025 at 2:05 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > > On Sun, May 18, 2025 at 1:09 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Sat, May 10, 2025 at 7:08 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > >
> > > > >
> > > > > Can we have a parameter like immediately_reserve in
> > > > > create_logical_slot API, similar to what we have for physical slots?
> > > > > We need to work out the details, but that should address the kind of
> > > > > use case you are worried about, unless I am missing something.
> > > >
> > > > Interesting idea. One concern in my mind is that in the use case I
> > > > mentioned above, users would need to carefully manage the extra
> > > > logical slot to keep the logical decoding active. The logical decoding
> > > > is deactivated on the standby as soon as users drop all logical slots
> > > > on the primary.
> > > >
> > >
> > > Yes, but the same is true for a physical slot in the case of physical
> > > replication used via primary_slot_name parameter.
> >
> > Could you elaborate on this?
> >
>
> I am trying to correlate with the case where standby no longer needs
> physical slot due to some reason like the standby machine failure, or
> say someone uses pg_createsubscriber on standby to make it subscriber,
> etc. In such a case, user needs to manually remove the physical slot
> on primary. There is difference in both cases but the point is one may
> need to manage physical slot as well.

Thank you for clarifying this. I see your point.

> >
> > I recently had a discussion with Ashtosh at PGConf.dev regarding an
> > alternative approach: introducing a new command syntax such as "ALTER
> > SYSTEM UPDATE wal_level TO 'logical'". In his presentation[1], he
> > outlined this proposed command as a means to modify specific GUC
> > parameters synchronously. The backend executing this command would
> > manage the transition, allowing users to interrupt the process via
> > Ctrl-C if necessary. In the specific context of wal_level change, this
> > command could be designed to reject operations like "ALTER SYSTEM
> > UPDATE wal_level TO 'minimal'" with an error, effectively preventing
> > undesirable wal_level transitions to or from 'minimal'. While this
> > approach shares similarities with our previous proposal of
> > implementing a dedicated SQL function for WAL level modifications, it
> > offers a more standardized interface for users.
> >
> > Though I find merit in this proposal, I remain uncertain about its
> > implementation details and whether it represents the optimal solution
> > for online wal_level changes, particularly given that our current
> > approach of automatic WAL level adjustment appears viable.
> >
>
> Yeah, I find the idea that the presence of a logical slot will allow
> the user to enable logical decoding/replication more appealing than
> this new alternative, leaving aside the challenges of realizing it.

I've drafted this idea. Here are summary for attached two patches:

0001 patch allows us to create a logical slot without WAL reservation.

0002 patch is the main patch for dynamically enabling/disabling
logical decoding when wal_level is 'replica'. It's in PoC state and
has a lot of XXX comments. One thing I think we need to consider is
that since disabling the logical decoding needs to write a WAL record
for standbys and happens when dropping the last logical slot which
needs to write a WAL record for standbys, it's possible that we write
a WAL record in a process shutdown during the process exit (e.g.,
ReplicationSlotRelease() and ReplicationSlotCleanup() are called by
ReplicationSlotShmemExit()). It might be safe as long as we do that
during calling before_shmem_exit callback but I'm not sure there is a
chance to do that during calling on_shmem_exit callbacks. It would be
better to somehow lazily disable the logical decoding.

Regards,

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

Attachment Content-Type Size
v1-0001-Allow-to-create-logical-slots-with-no-WAL-reserva.patch application/octet-stream 13.5 KB
v1-0002-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 46.8 KB

From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-04 10:10:38
Message-ID: CAJpy0uD2nKJ=DPFwnAdXZiHj9MKWdMS-tZc9zOqB-7yfWzN8Qg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 4, 2025 at 6:41 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Tue, May 20, 2025 at 9:54 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > Yeah, I find the idea that the presence of a logical slot will allow
> > the user to enable logical decoding/replication more appealing than
> > this new alternative, leaving aside the challenges of realizing it.

+1. This idea appears more user-friendly and easier to understand
compared to other approaches, such as having multiple GUCs or using
ALTER SYSTEM.

> I've drafted this idea. Here are summary for attached two patches:
>
> 0001 patch allows us to create a logical slot without WAL reservation.
>
> 0002 patch is the main patch for dynamically enabling/disabling
> logical decoding when wal_level is 'replica'.

Thank You for the patches. I have done some initial testing, it seems
to be working well. I will do more testing and review and will share
further feedback.

thanks
Shveta


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-06 10:02:45
Message-ID: CAJpy0uDW6BpNXLZ0AaP=_GU6pCsZf_7Sk2R0Ti+ov+EO6ruMkg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 4, 2025 at 3:40 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jun 4, 2025 at 6:41 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Tue, May 20, 2025 at 9:54 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > > Yeah, I find the idea that the presence of a logical slot will allow
> > > the user to enable logical decoding/replication more appealing than
> > > this new alternative, leaving aside the challenges of realizing it.
>
> +1. This idea appears more user-friendly and easier to understand
> compared to other approaches, such as having multiple GUCs or using
> ALTER SYSTEM.
>
> > I've drafted this idea. Here are summary for attached two patches:
> >
> > 0001 patch allows us to create a logical slot without WAL reservation.
> >
> > 0002 patch is the main patch for dynamically enabling/disabling
> > logical decoding when wal_level is 'replica'.
>
> Thank You for the patches. I have done some initial testing, it seems
> to be working well. I will do more testing and review and will share
> further feedback.

I reviewed further and had few concerns:

1)
We now invalidate slots on standby if the primary (with
wal_level=replica) has dropped the last logical slot and internally
reverted its runtime (effective) wal_level back to replica. Consider
the following scenario involving a cascaded logical replication setup:

a) The publisher is configured with wal_level = replica and has
created a publication (pub1).
b) A subscriber server creates a subscription (sub1) to pub1. As part
of the slot creation for sub1, the publisher's effective wal_level is
switched to logical.
c) The publisher also has a physical standby, which in turn has its
own logical subscriber, named standby_sub1.

At this point, everything works as expected i.e. changes from the
publisher flow through the physical standby and are replicated to
standby_sub1. Now if the user drops sub1, the replication slot on the
primary is also dropped. Since this was the last logical slot, the
primary automatically switches its effective wal_level back to
replica. This change propagates to the standby, causing it to
invalidate the slot for standby_sub1. As a result, the standby logs
the following error:

STATEMENT: START_REPLICATION SLOT "standby_sub1" LOGICAL 0/0 (...)
ERROR: logical decoding needs to be enabled on the primary

Even if we manually recreate a logical slot on the primary afterward,
the standby_sub1 subscriber is not able to proceed:
ERROR: can no longer access replication slot "standby_sub1"
DETAIL: This replication slot has been invalidated due to
"wal_level_insufficient".

So the removal of the logical subscriber for the publisher has somehow
restricted the logical subscriber of standby to work. Is this
behaviour acceptable?

Without this feature, if I manually switch back wal_level to replica
on primary, then it will fail to start. This makes the issue obvious
and prevents misconfiguration.
FATAL: logical replication slot "sub2" exists, but "wal_level" < "logical"
HINT: Change "wal_level" to be "logical" or higher.

But the current behaviour is harder to diagnose, as the problem is
effectively hidden behind subscription/slot creation/deletion.

2)
'show effective_wal_level' shows output as 'logical' if a slot exists
on primary. But on physical standby, it still shows it as 'replica'
even in the presence of slots. Is this intentional?

3)
I haven’t tested this yet, but I’d like to discuss what the expected
behavior should be if a slot exists on the primary but is marked as
invalidated. Will an invalidated slot still cause the effective
wal_level to remain at logical, or will invalidating the only logical
slot trigger a switch back to replica?
There is a chance that a slot with un-reserved wal may be invalidated
due to time-out.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-06 21:13:23
Message-ID: CAD21AoC70bOrtMXGA85Ltk8hm0cHFYQ+JfRuofbcQUz3CbHLSg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jun 6, 2025 at 3:02 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jun 4, 2025 at 3:40 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 4, 2025 at 6:41 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Tue, May 20, 2025 at 9:54 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > >
> > > > Yeah, I find the idea that the presence of a logical slot will allow
> > > > the user to enable logical decoding/replication more appealing than
> > > > this new alternative, leaving aside the challenges of realizing it.
> >
> > +1. This idea appears more user-friendly and easier to understand
> > compared to other approaches, such as having multiple GUCs or using
> > ALTER SYSTEM.
> >
> > > I've drafted this idea. Here are summary for attached two patches:
> > >
> > > 0001 patch allows us to create a logical slot without WAL reservation.
> > >
> > > 0002 patch is the main patch for dynamically enabling/disabling
> > > logical decoding when wal_level is 'replica'.
> >
> > Thank You for the patches. I have done some initial testing, it seems
> > to be working well. I will do more testing and review and will share
> > further feedback.
>
> I reviewed further and had few concerns:

Thank you for reviewing this feature!

>
> 1)
> We now invalidate slots on standby if the primary (with
> wal_level=replica) has dropped the last logical slot and internally
> reverted its runtime (effective) wal_level back to replica. Consider
> the following scenario involving a cascaded logical replication setup:
>
> a) The publisher is configured with wal_level = replica and has
> created a publication (pub1).
> b) A subscriber server creates a subscription (sub1) to pub1. As part
> of the slot creation for sub1, the publisher's effective wal_level is
> switched to logical.
> c) The publisher also has a physical standby, which in turn has its
> own logical subscriber, named standby_sub1.
>
> At this point, everything works as expected i.e. changes from the
> publisher flow through the physical standby and are replicated to
> standby_sub1. Now if the user drops sub1, the replication slot on the
> primary is also dropped. Since this was the last logical slot, the
> primary automatically switches its effective wal_level back to
> replica. This change propagates to the standby, causing it to
> invalidate the slot for standby_sub1. As a result, the standby logs
> the following error:
>
> STATEMENT: START_REPLICATION SLOT "standby_sub1" LOGICAL 0/0 (...)
> ERROR: logical decoding needs to be enabled on the primary
>
> Even if we manually recreate a logical slot on the primary afterward,
> the standby_sub1 subscriber is not able to proceed:
> ERROR: can no longer access replication slot "standby_sub1"
> DETAIL: This replication slot has been invalidated due to
> "wal_level_insufficient".
>
> So the removal of the logical subscriber for the publisher has somehow
> restricted the logical subscriber of standby to work. Is this
> behaviour acceptable?
>
> Without this feature, if I manually switch back wal_level to replica
> on primary, then it will fail to start. This makes the issue obvious
> and prevents misconfiguration.
> FATAL: logical replication slot "sub2" exists, but "wal_level" < "logical"
> HINT: Change "wal_level" to be "logical" or higher.
>
> But the current behaviour is harder to diagnose, as the problem is
> effectively hidden behind subscription/slot creation/deletion.

The most upstream server in replication configuration would carefully
need to keep having at least one logical slot. One way to keep
effective_wal_level 'logical' on the publisher where wal_level =
'replica' is to have a logical slot without WAL reservation that is
not relevant with any subscriptions. It could require an extra logical
slot but seems workable. Does it resolve this concern?

> 2)
> 'show effective_wal_level' shows output as 'logical' if a slot exists
> on primary. But on physical standby, it still shows it as 'replica'
> even in the presence of slots. Is this intentional?

Yes. I think we should disallow the standbys to create a logical slot
as long as they use wal_level = 'replica', because otherwise the
standby would need to invalidate the logical slot at a promotion.
Which could cause a large down time in a failover case.

> 3)
> I haven’t tested this yet, but I’d like to discuss what the expected
> behavior should be if a slot exists on the primary but is marked as
> invalidated. Will an invalidated slot still cause the effective
> wal_level to remain at logical, or will invalidating the only logical
> slot trigger a switch back to replica?
> There is a chance that a slot with un-reserved wal may be invalidated
> due to time-out.

Good point. I think we don't need to decrease the effective_wal_level
to 'replica' even if we invalidate all logical slots. We need neither
WAL reservation nor dead tuple retention in order to set
effective_wal_level to 'logical' so I think it's straightforward that
effective_wal_level value depends on only the presence of logical
slots. If dle_replication_slot_timeout affects also logical slots
created with immeidately_reserve=false, we might want to exclude them
to avoid confusion.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-09 03:57:32
Message-ID: CAJpy0uD0Qf5WBZv6-qRqQTP9jEAbLH6NFGi=y4fihMMieKVHAA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sat, Jun 7, 2025 at 2:44 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Fri, Jun 6, 2025 at 3:02 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 4, 2025 at 3:40 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jun 4, 2025 at 6:41 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Tue, May 20, 2025 at 9:54 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > >
> > > > > Yeah, I find the idea that the presence of a logical slot will allow
> > > > > the user to enable logical decoding/replication more appealing than
> > > > > this new alternative, leaving aside the challenges of realizing it.
> > >
> > > +1. This idea appears more user-friendly and easier to understand
> > > compared to other approaches, such as having multiple GUCs or using
> > > ALTER SYSTEM.
> > >
> > > > I've drafted this idea. Here are summary for attached two patches:
> > > >
> > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > > >
> > > > 0002 patch is the main patch for dynamically enabling/disabling
> > > > logical decoding when wal_level is 'replica'.
> > >
> > > Thank You for the patches. I have done some initial testing, it seems
> > > to be working well. I will do more testing and review and will share
> > > further feedback.
> >
> > I reviewed further and had few concerns:
>
> Thank you for reviewing this feature!
>
> >
> > 1)
> > We now invalidate slots on standby if the primary (with
> > wal_level=replica) has dropped the last logical slot and internally
> > reverted its runtime (effective) wal_level back to replica. Consider
> > the following scenario involving a cascaded logical replication setup:
> >
> > a) The publisher is configured with wal_level = replica and has
> > created a publication (pub1).
> > b) A subscriber server creates a subscription (sub1) to pub1. As part
> > of the slot creation for sub1, the publisher's effective wal_level is
> > switched to logical.
> > c) The publisher also has a physical standby, which in turn has its
> > own logical subscriber, named standby_sub1.
> >
> > At this point, everything works as expected i.e. changes from the
> > publisher flow through the physical standby and are replicated to
> > standby_sub1. Now if the user drops sub1, the replication slot on the
> > primary is also dropped. Since this was the last logical slot, the
> > primary automatically switches its effective wal_level back to
> > replica. This change propagates to the standby, causing it to
> > invalidate the slot for standby_sub1. As a result, the standby logs
> > the following error:
> >
> > STATEMENT: START_REPLICATION SLOT "standby_sub1" LOGICAL 0/0 (...)
> > ERROR: logical decoding needs to be enabled on the primary
> >
> > Even if we manually recreate a logical slot on the primary afterward,
> > the standby_sub1 subscriber is not able to proceed:
> > ERROR: can no longer access replication slot "standby_sub1"
> > DETAIL: This replication slot has been invalidated due to
> > "wal_level_insufficient".
> >
> > So the removal of the logical subscriber for the publisher has somehow
> > restricted the logical subscriber of standby to work. Is this
> > behaviour acceptable?
> >
> > Without this feature, if I manually switch back wal_level to replica
> > on primary, then it will fail to start. This makes the issue obvious
> > and prevents misconfiguration.
> > FATAL: logical replication slot "sub2" exists, but "wal_level" < "logical"
> > HINT: Change "wal_level" to be "logical" or higher.
> >
> > But the current behaviour is harder to diagnose, as the problem is
> > effectively hidden behind subscription/slot creation/deletion.
>
> The most upstream server in replication configuration would carefully
> need to keep having at least one logical slot. One way to keep
> effective_wal_level 'logical' on the publisher where wal_level =
> 'replica' is to have a logical slot without WAL reservation that is
> not relevant with any subscriptions. It could require an extra logical
> slot but seems workable. Does it resolve this concern?
>

Yes, I agree that publishers should have a separate slot (not related
with any subscription) without WAL reservation to retain
effective_wal_level as logical when wal_level is replica. But the
question is how can that be ensured? Will it be user's responsibility
to always create that slot? If user has already some subscriptions
subscribing to most upstream server, then while setting up logical
replication on physical standby at a later stage, user will not even
encounter the error:
ERROR: logical decoding needs to be enabled on the primary,
HINT: Set wal_level >= logical or create at least one logical slot on
the primary.

And in lack of such error, users may always end up in the above
explained situation.

> > 2)
> > 'show effective_wal_level' shows output as 'logical' if a slot exists
> > on primary. But on physical standby, it still shows it as 'replica'
> > even in the presence of slots. Is this intentional?
>
> Yes. I think we should disallow the standbys to create a logical slot
> as long as they use wal_level = 'replica', because otherwise the
> standby would need to invalidate the logical slot at a promotion.
> Which could cause a large down time in a failover case.

Do you mean even if primary is running on effective_wal_level=logical,
we shall disallow slot-creation on standby if standby has
wal_level=replica? It means the $subject's enhancement is only valid
on primary?

Or the other way could be that we can have 2 trigger points for
enabling effective_wal_level to logical on primary:
1) One is when a logical slot is created on primary.
2) Another is when a logical slot is created on any of its physical standby.

We need to maintain these 2 separately as drop of last primary's slot
should not toggle it back to replica when any of its physical
standbys still need it. But if a publisher has multiple physical
standbys, then it will need extra handling i.e. last logical-slot drop
on standby1 should not end up toggling effective_wal_level to replica
when standby2 still has some logical slots. I am somehow trying to
think of a way where we have that extra slot without the user's
intervention.

>
> > 3)
> > I haven’t tested this yet, but I’d like to discuss what the expected
> > behavior should be if a slot exists on the primary but is marked as
> > invalidated. Will an invalidated slot still cause the effective
> > wal_level to remain at logical, or will invalidating the only logical
> > slot trigger a switch back to replica?
> > There is a chance that a slot with un-reserved wal may be invalidated
> > due to time-out.
>
> Good point. I think we don't need to decrease the effective_wal_level
> to 'replica' even if we invalidate all logical slots. We need neither
> WAL reservation nor dead tuple retention in order to set
> effective_wal_level to 'logical' so I think it's straightforward that
> effective_wal_level value depends on only the presence of logical
> slots. If dle_replication_slot_timeout affects also logical slots
> created with immeidately_reserve=false, we might want to exclude them
> to avoid confusion.
>

Yes, we shall exclude such slot from timeout based invalidation. As
there are chances that if a slot is invalidated, user may drop it
anytime.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-10 21:00:55
Message-ID: CAD21AoA4j_Qb8k-YFb-sT1Ckw=wf3ZnM6miLT2BH_8vp=S8FGQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, Jun 8, 2025 at 8:57 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Sat, Jun 7, 2025 at 2:44 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Fri, Jun 6, 2025 at 3:02 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jun 4, 2025 at 3:40 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Jun 4, 2025 at 6:41 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Tue, May 20, 2025 at 9:54 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > Yeah, I find the idea that the presence of a logical slot will allow
> > > > > > the user to enable logical decoding/replication more appealing than
> > > > > > this new alternative, leaving aside the challenges of realizing it.
> > > >
> > > > +1. This idea appears more user-friendly and easier to understand
> > > > compared to other approaches, such as having multiple GUCs or using
> > > > ALTER SYSTEM.
> > > >
> > > > > I've drafted this idea. Here are summary for attached two patches:
> > > > >
> > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > > > >
> > > > > 0002 patch is the main patch for dynamically enabling/disabling
> > > > > logical decoding when wal_level is 'replica'.
> > > >
> > > > Thank You for the patches. I have done some initial testing, it seems
> > > > to be working well. I will do more testing and review and will share
> > > > further feedback.
> > >
> > > I reviewed further and had few concerns:
> >
> > Thank you for reviewing this feature!
> >
> > >
> > > 1)
> > > We now invalidate slots on standby if the primary (with
> > > wal_level=replica) has dropped the last logical slot and internally
> > > reverted its runtime (effective) wal_level back to replica. Consider
> > > the following scenario involving a cascaded logical replication setup:
> > >
> > > a) The publisher is configured with wal_level = replica and has
> > > created a publication (pub1).
> > > b) A subscriber server creates a subscription (sub1) to pub1. As part
> > > of the slot creation for sub1, the publisher's effective wal_level is
> > > switched to logical.
> > > c) The publisher also has a physical standby, which in turn has its
> > > own logical subscriber, named standby_sub1.
> > >
> > > At this point, everything works as expected i.e. changes from the
> > > publisher flow through the physical standby and are replicated to
> > > standby_sub1. Now if the user drops sub1, the replication slot on the
> > > primary is also dropped. Since this was the last logical slot, the
> > > primary automatically switches its effective wal_level back to
> > > replica. This change propagates to the standby, causing it to
> > > invalidate the slot for standby_sub1. As a result, the standby logs
> > > the following error:
> > >
> > > STATEMENT: START_REPLICATION SLOT "standby_sub1" LOGICAL 0/0 (...)
> > > ERROR: logical decoding needs to be enabled on the primary
> > >
> > > Even if we manually recreate a logical slot on the primary afterward,
> > > the standby_sub1 subscriber is not able to proceed:
> > > ERROR: can no longer access replication slot "standby_sub1"
> > > DETAIL: This replication slot has been invalidated due to
> > > "wal_level_insufficient".
> > >
> > > So the removal of the logical subscriber for the publisher has somehow
> > > restricted the logical subscriber of standby to work. Is this
> > > behaviour acceptable?
> > >
> > > Without this feature, if I manually switch back wal_level to replica
> > > on primary, then it will fail to start. This makes the issue obvious
> > > and prevents misconfiguration.
> > > FATAL: logical replication slot "sub2" exists, but "wal_level" < "logical"
> > > HINT: Change "wal_level" to be "logical" or higher.
> > >
> > > But the current behaviour is harder to diagnose, as the problem is
> > > effectively hidden behind subscription/slot creation/deletion.
> >
> > The most upstream server in replication configuration would carefully
> > need to keep having at least one logical slot. One way to keep
> > effective_wal_level 'logical' on the publisher where wal_level =
> > 'replica' is to have a logical slot without WAL reservation that is
> > not relevant with any subscriptions. It could require an extra logical
> > slot but seems workable. Does it resolve this concern?
> >
>
> Yes, I agree that publishers should have a separate slot (not related
> with any subscription) without WAL reservation to retain
> effective_wal_level as logical when wal_level is replica. But the
> question is how can that be ensured? Will it be user's responsibility
> to always create that slot? If user has already some subscriptions
> subscribing to most upstream server, then while setting up logical
> replication on physical standby at a later stage, user will not even
> encounter the error:
> ERROR: logical decoding needs to be enabled on the primary,
> HINT: Set wal_level >= logical or create at least one logical slot on
> the primary.
>
> And in lack of such error, users may always end up in the above
> explained situation.

I think it's the user's responsibility to keep at least one logical
slot. It seems that setting wal_level to 'logical' would be the most
reliable solution for this case. We might want to provide a way to
keep 'logical' WAL level somehow but I don't have a good idea for now.

> > > 2)
> > > 'show effective_wal_level' shows output as 'logical' if a slot exists
> > > on primary. But on physical standby, it still shows it as 'replica'
> > > even in the presence of slots. Is this intentional?
> >
> > Yes. I think we should disallow the standbys to create a logical slot
> > as long as they use wal_level = 'replica', because otherwise the
> > standby would need to invalidate the logical slot at a promotion.
> > Which could cause a large down time in a failover case.
>
> Do you mean even if primary is running on effective_wal_level=logical,
> we shall disallow slot-creation on standby if standby has
> wal_level=replica? It means the $subject's enhancement is only valid
> on primary?

Thank you for pointing it out, my assumption was wrong. Even if the
standby sets wal_level='replica', it should be able to create logical
slots if the primary enables the logical decoding, and it should be
able to continue using it even after the promotion. I"ve updated the
patch accordingly.

>
> Or the other way could be that we can have 2 trigger points for
> enabling effective_wal_level to logical on primary:
> 1) One is when a logical slot is created on primary.
> 2) Another is when a logical slot is created on any of its physical standby.
>
> We need to maintain these 2 separately as drop of last primary's slot
> should not toggle it back to replica when any of its physical
> standbys still need it. But if a publisher has multiple physical
> standbys, then it will need extra handling i.e. last logical-slot drop
> on standby1 should not end up toggling effective_wal_level to replica
> when standby2 still has some logical slots. I am somehow trying to
> think of a way where we have that extra slot without the user's
> intervention.

Considering cascading replication cases too, 2) could be tricky as
cascaded standbys need to propagate the information of logical slot
creation up to the most upstream server.

Regards,

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

Attachment Content-Type Size
v2-0001-Allow-to-create-logical-slots-with-no-WAL-reserva.patch application/octet-stream 13.5 KB
v2-0002-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 51.0 KB

From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-17 06:48:07
Message-ID: CAJpy0uB03yEovgp_HK7csBn=g03Mi9=uAAgVO6VXT8OUws9vkQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 11, 2025 at 2:31 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> I think it's the user's responsibility to keep at least one logical
> slot. It seems that setting wal_level to 'logical' would be the most
> reliable solution for this case. We might want to provide a way to
> keep 'logical' WAL level somehow but I don't have a good idea for now.
>

Okay, Let me think more on this.

>
> Considering cascading replication cases too, 2) could be tricky as
> cascaded standbys need to propagate the information of logical slot
> creation up to the most upstream server.
>

Yes, I understand the challenges here.

Thanks for the v2 patches, few concerns:

1)
Now when the slot on standby is invalidated due to effective_wal_level
switched back to replica and if we restart standby, it fails to
restart even if wal_level is explicitly changed to logical in conf
file.

FATAL: logical replication slot "slot_st" exists, but logical
decoding is not enabled
HINT: Change "wal_level" to be "replica" or higher.

2)
I see that when primary switches back its effective wal_level to
replica while standby has wal_level=logical in conf file, then standby
has this status:

postgres=# show wal_level;
wal_level
-----------
logical

postgres=# show effective_wal_level;
effective_wal_level
---------------------
replica

Is this correct? Can effective_wal_level be < wal_level anytime? I
feel it can be greater but never lesser.

3)
When standby invalidate obsolete slots due to effective_wal_level on
primary changed to replica, it dumps below:
LOG: invalidating obsolete replication slot "slot_st2"
DETAIL: Logical decoding on standby requires "wal_level" >= "logical"
on the primary server

Shall we update this message as well to convey about slot-presence on primary.
DETAIL: Logical decoding on standby requires "wal_level" >= "logical"
or presence of logical slot on the primary server.

4)
I see that the slotsync worker is running all the time now as against
the previous behaviour where it will not start if wal_level is less
than logical or switched to '< logical' anytime. Even with wal_level
and effective_wal_level set to replica, slot-sync keeps on attempting
synchronization. This does not look correct. I think we need to find a
way to stop sot-sync worker when effective_wal_level is switched to
replica from logical.

5)
Can you please help me understand the changes at [1].

a) Why is it needed when we have code logic at [2]
b) in [1], why do we check n_inuse_logical_slots on standby and then
make decisions? Why not to disable logical-decoding directly just like
[2]

[1]:
+ if (xlrec.wal_level == WAL_LEVEL_LOGICAL)
+ {
+ /*
+ * If the primary increase WAL level to 'logical', we can
+ * unconditionally enable the logical decoding on the standby.
+ */
+ UpdateLogicalDecodingStatus(true);
+ }
+ else if (xlrec.wal_level == WAL_LEVEL_REPLICA &&
+ pg_atomic_read_u32(&ReplicationSlotCtl->n_inuse_logical_slots) == 0)
+ {
+ /*
+ * Disable the logical decoding if there is no in-use logical slot
+ * on the standby.
+ */
+ UpdateLogicalDecodingStatus(false);
+ }

[2]:
+ else if (info == XLOG_LOGICAL_DECODING_STATUS_CHANGE)
+ {
+ bool logical_decoding;
+
+ memcpy(&logical_decoding, XLogRecGetData(record), sizeof(bool));
+ UpdateLogicalDecodingStatus(logical_decoding);
+
+ /*
+ * Invalidate logical slots if we are in hot standby and the primary
+ * disabled the logical decoding.
+ */
+ if (!logical_decoding && InRecovery && InHotStandby)
+ InvalidateObsoleteReplicationSlots(RS_INVAL_WAL_LEVEL,
+ 0, InvalidOid,
+ InvalidTransactionId);
+
+ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ ControlFile->logicalDecodingEnabled = logical_decoding;
+ UpdateControlFile();
+ LWLockRelease(ControlFileLock);
+ }

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-18 00:36:06
Message-ID: CAD21AoC6zSkzpdmmeCUn1+YmcAw4pDc21OehtpDp0Rd=cF2TYw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jun 16, 2025 at 11:48 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jun 11, 2025 at 2:31 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > I think it's the user's responsibility to keep at least one logical
> > slot. It seems that setting wal_level to 'logical' would be the most
> > reliable solution for this case. We might want to provide a way to
> > keep 'logical' WAL level somehow but I don't have a good idea for now.
> >
>
> Okay, Let me think more on this.
>
> >
> > Considering cascading replication cases too, 2) could be tricky as
> > cascaded standbys need to propagate the information of logical slot
> > creation up to the most upstream server.
> >
>
> Yes, I understand the challenges here.
>
> Thanks for the v2 patches, few concerns:

Thank you for the comments!

> 1)
> Now when the slot on standby is invalidated due to effective_wal_level
> switched back to replica and if we restart standby, it fails to
> restart even if wal_level is explicitly changed to logical in conf
> file.
>
> FATAL: logical replication slot "slot_st" exists, but logical
> decoding is not enabled
> HINT: Change "wal_level" to be "replica" or higher.

Good catch, we should fix it.
>
> 2)
> I see that when primary switches back its effective wal_level to
> replica while standby has wal_level=logical in conf file, then standby
> has this status:
>
> postgres=# show wal_level;
> wal_level
> -----------
> logical
>
> postgres=# show effective_wal_level;
> effective_wal_level
> ---------------------
> replica
>
> Is this correct? Can effective_wal_level be < wal_level anytime? I
> feel it can be greater but never lesser.

Hmm, I think we need to define what value we should show in
effective_wal_level on standbys because the standbys actually are not
writing any WALs and whether or not the logical decoding is enabled on
the standbys depends on the primary.

In the previous version patch, the standby's effective_wal_level value
depended solely on the standby's wal_level value. However, it was
confusing in a sense because it's possible that the logical decoding
could be available even though effective_wal_level is 'replica' if the
primary already enables it. One idea is that given that the logical
decoding availability and effective_wal_level value are independent in
principle, it's better to provide a SQL function to get the logical
decoding status so that users can check the logical decoding
availability without checking effective_wal_level. With that function,
it might make sense to revert back the behavior to the previous one.
That is, on the primary the effective_wal_level value is always
greater than or equal to wal_level whereas on the standbys it's always
the same as wal_level, and users would be able to check the logical
decoding availability using the SQL function. Or it might also be
worth considering to show effective_wal_level as NULL on standbys.

>
> 3)
> When standby invalidate obsolete slots due to effective_wal_level on
> primary changed to replica, it dumps below:
> LOG: invalidating obsolete replication slot "slot_st2"
> DETAIL: Logical decoding on standby requires "wal_level" >= "logical"
> on the primary server
>
> Shall we update this message as well to convey about slot-presence on primary.
> DETAIL: Logical decoding on standby requires "wal_level" >= "logical"
> or presence of logical slot on the primary server.

Will fix.

> 4)
> I see that the slotsync worker is running all the time now as against
> the previous behaviour where it will not start if wal_level is less
> than logical or switched to '< logical' anytime. Even with wal_level
> and effective_wal_level set to replica, slot-sync keeps on attempting
> synchronization. This does not look correct. I think we need to find a
> way to stop sot-sync worker when effective_wal_level is switched to
> replica from logical.

Right, will fix.

> 5)
> Can you please help me understand the changes at [1].
>
> a) Why is it needed when we have code logic at [2]

This is because we use XLOG_LOGICAL_DECODING_STATUS_CHANGE record only
for changing the logical decoding status online (i.e., without
restarting the server). So I think we still these part of code in
cases where we enable/disable the logical decoding by changing the
wal_level value with restarting the server

Suppose that both the primary and the standby set wal_level='replica',
the logical decoding is not available on both sides. If the primary
restarts with wal_level='logical', it doesn't write an
XLOG_LOGICAL_DECODING_STATUS_CHANGE record.

Another case is that suppose that the primary sets wal_level='logical'
and the standby sets wal_level='replica', the logical decoding is
available on both sides. If the primary restarts with
wal_level='replica' we need to somehow tell the standby the fact that
the logical decoding gets disabled. (BTW I realized we need to
invalidate the logical slots in this case too).

> b) in [1], why do we check n_inuse_logical_slots on standby and then
> make decisions? Why not to disable logical-decoding directly just like
> [2]

It seems the code is incorrect. We should disable the logical decoding
anyway if the primary disables it. Will fix.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-18 04:07:34
Message-ID: CAJpy0uCHiCPt0M+j4+kUn=0CXnO=95itRMgmcAWriV93sZhv-w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 18, 2025 at 6:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Thank you for the comments!
>
> >
> > 2)
> > I see that when primary switches back its effective wal_level to
> > replica while standby has wal_level=logical in conf file, then standby
> > has this status:
> >
> > postgres=# show wal_level;
> > wal_level
> > -----------
> > logical
> >
> > postgres=# show effective_wal_level;
> > effective_wal_level
> > ---------------------
> > replica
> >
> > Is this correct? Can effective_wal_level be < wal_level anytime? I
> > feel it can be greater but never lesser.
>
> Hmm, I think we need to define what value we should show in
> effective_wal_level on standbys because the standbys actually are not
> writing any WALs and whether or not the logical decoding is enabled on
> the standbys depends on the primary.
>
> In the previous version patch, the standby's effective_wal_level value
> depended solely on the standby's wal_level value. However, it was
> confusing in a sense because it's possible that the logical decoding
> could be available even though effective_wal_level is 'replica' if the
> primary already enables it. One idea is that given that the logical
> decoding availability and effective_wal_level value are independent in
> principle, it's better to provide a SQL function to get the logical
> decoding status so that users can check the logical decoding
> availability without checking effective_wal_level. With that function,
> it might make sense to revert back the behavior to the previous one.
> That is, on the primary the effective_wal_level value is always
> greater than or equal to wal_level whereas on the standbys it's always
> the same as wal_level, and users would be able to check the logical
> decoding availability using the SQL function. Or it might also be
> worth considering to show effective_wal_level as NULL on standbys.

Yes, that is one idea. It will resolve the confusion.
But I was thinking, instead of having one new GUC + a SQL function,
can we have a GUC alone, which shows logical_decoding status plus the
cause of that. The new GUC will be applicable on both primary and
standby. As an example, let's say we name it as
logical_decoding_status, then it can have these values (
<status>_<cause>):

enabled_wal_level_logical: valid both
for primary, standby
enabled_effective_wal_level_logical: valid only for primary
enabled_cascaded_logical_decoding valid only for standby
disabled :
valid both for primary, standby

'enabled_cascaded_logical_decoding' will indicate that logical
decoding is enabled on standby (even when its own wal_level=replica)
as a cascaded effect from primary. It can be possible either due to
primary's wal_level=logical or logical slot being present on primary.

> >
> > 3)
> > When standby invalidate obsolete slots due to effective_wal_level on
> > primary changed to replica, it dumps below:
> > LOG: invalidating obsolete replication slot "slot_st2"
> > DETAIL: Logical decoding on standby requires "wal_level" >= "logical"
> > on the primary server
> >
> > Shall we update this message as well to convey about slot-presence on primary.
> > DETAIL: Logical decoding on standby requires "wal_level" >= "logical"
> > or presence of logical slot on the primary server.
>
> Will fix.
>
> > 4)
> > I see that the slotsync worker is running all the time now as against
> > the previous behaviour where it will not start if wal_level is less
> > than logical or switched to '< logical' anytime. Even with wal_level
> > and effective_wal_level set to replica, slot-sync keeps on attempting
> > synchronization. This does not look correct. I think we need to find a
> > way to stop sot-sync worker when effective_wal_level is switched to
> > replica from logical.
>
> Right, will fix.
>
> > 5)
> > Can you please help me understand the changes at [1].
> >
> > a) Why is it needed when we have code logic at [2]
>
> This is because we use XLOG_LOGICAL_DECODING_STATUS_CHANGE record only
> for changing the logical decoding status online (i.e., without
> restarting the server). So I think we still these part of code in
> cases where we enable/disable the logical decoding by changing the
> wal_level value with restarting the server
>
> Suppose that both the primary and the standby set wal_level='replica',
> the logical decoding is not available on both sides. If the primary
> restarts with wal_level='logical', it doesn't write an
> XLOG_LOGICAL_DECODING_STATUS_CHANGE record.
>
> Another case is that suppose that the primary sets wal_level='logical'
> and the standby sets wal_level='replica', the logical decoding is
> available on both sides. If the primary restarts with
> wal_level='replica' we need to somehow tell the standby the fact that
> the logical decoding gets disabled.

Okay, I understand it now.

> (BTW I realized we need to
> invalidate the logical slots in this case too).
>

Yes, the behaviour should be the same. The differences in behaviour
for the 2 cases I pointed, confused me at the very first place.

> > b) in [1], why do we check n_inuse_logical_slots on standby and then
> > make decisions? Why not to disable logical-decoding directly just like
> > [2]
>
> It seems the code is incorrect. We should disable the logical decoding
> anyway if the primary disables it. Will fix.
>

I agree. So now case [1] behaviour will be exactly the same as case
[2] i.e. invalidate the slot and don't check slots-usage on standby
before invalidating.

thanks
Shveta


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-18 09:09:12
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > 0001 patch allows us to create a logical slot without WAL reservation.

Thanks for the patch and sorry to be late in this conversation.

The thing that worry me a bit with this is that that could be easy to attempt
to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
by mistake on the primary. I think that this mistake is more likely to happen
with a logical slot as compared to a physical slot.

IIUC the idea is to "just" increase WAL level to 'logical' so that one could then
be allowed to make use of logical decoding from the standby. The primary goal
of logical decoding from standby is to move some load from the primay to
the standby i.e we don't expect/want the logical slot to be used on the primary.

So what about making sure that if a logical slot is created with immediately_reserve
set to false then no one can use it? (That would ensure that WAL reservation
will not happen).

That said, we might also want to create another parameter name (than
immediately_reserve) to better reflect this behavior (if we move that way).

Thoughts?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-18 09:52:59
Message-ID: CAJpy0uDsBgNfnTWayrJpLzSVYPLEMAoB2skqjQ3fiW1tg_vDMQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
>
> Thanks for the patch and sorry to be late in this conversation.
>
> The thing that worry me a bit with this is that that could be easy to attempt
> to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> by mistake on the primary. I think that this mistake is more likely to happen
> with a logical slot as compared to a physical slot.
>

Yes, agreed. Another concern is the possibility of someone
intentionally using it and associating it with a subscription. If the
subscription is later dropped, it could also cause the slot to be
removed. In cases where this is the only slot on the primary, it may
render the standby slots unusable as well. Refer the problem described
in [1]

> IIUC the idea is to "just" increase WAL level to 'logical' so that one could then
> be allowed to make use of logical decoding from the standby. The primary goal
> of logical decoding from standby is to move some load from the primay to
> the standby i.e we don't expect/want the logical slot to be used on the primary.
>
> So what about making sure that if a logical slot is created with immediately_reserve
> set to false then no one can use it? (That would ensure that WAL reservation
> will not happen).
>

+1.
One approach is to reserve a specific slot name for this purpose. If
such a slot is created, we can internally set immediately_reserve to
false and also prevent it from being used. The only permitted user
action on this slot would be to drop it using
pg_drop_replication_slot() instead of being dropped as part of
subscription-drop.
Another concern is ensuring that users actually create this slot. If
there is already an active subscription subscribed to the primary, the
effective_wal_level will be set to logical already, allowing logical
decoding on the standby to proceed without issue. In such a case, the
user might not bother to create additional slots (same as problem
described in [1])) and later may unintentionally end up making standby
slots unusable. Any ideas on how to ensure it?

> That said, we might also want to create another parameter name (than
> immediately_reserve) to better reflect this behavior (if we move that way).
>
> Thoughts?

Or we could avoid exposing control of immediately_reserve to the user
altogether? Instead, we reserve a specific slot name and ensure that
it never reserves WAL in the future by preventing it from being
consumed under any circumstances (as you suggested).

[1]: https://www.postgresql.org/message-id/CAJpy0uDW6BpNXLZ0AaP%3D_GU6pCsZf_7Sk2R0Ti%2Bov%2BEO6ruMkg%40mail.gmail.com

thanks
Shveta


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-19 09:00:25
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Wed, Jun 18, 2025 at 03:22:59PM +0530, shveta malik wrote:
> On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > IIUC the idea is to "just" increase WAL level to 'logical' so that one could then
> > be allowed to make use of logical decoding from the standby. The primary goal
> > of logical decoding from standby is to move some load from the primay to
> > the standby i.e we don't expect/want the logical slot to be used on the primary.
> >
> > So what about making sure that if a logical slot is created with immediately_reserve
> > set to false then no one can use it? (That would ensure that WAL reservation
> > will not happen).
> >
>
> Another concern is ensuring that users actually create this slot. If
> there is already an active subscription subscribed to the primary, the
> effective_wal_level will be set to logical already, allowing logical
> decoding on the standby to proceed without issue. In such a case, the
> user might not bother to create additional slots (same as problem
> described in [1])) and later may unintentionally end up making standby
> slots unusable. Any ideas on how to ensure it?

> > That said, we might also want to create another parameter name (than
> > immediately_reserve) to better reflect this behavior (if we move that way).
> >
> > Thoughts?
>
> Or we could avoid exposing control of immediately_reserve to the user
> altogether? Instead, we reserve a specific slot name and ensure that
> it never reserves WAL in the future by preventing it from being
> consumed under any circumstances (as you suggested).

I wonder if a way to address the concerns that we shared above is to use a
mixed approach like:

- Forget the immediately_reserve idea
- If a user creates a logical slot then we automatically switch to wal_level =
logical (if not already done): I think that's a nice user experience
- *and* provide a new API pg_activate_logical_decoding(), if the user has no
need to create a logical slot on the primary (wants to use the standby to offload
all the logical decoding)

So if the user also uses a logical slot on the primary (for real..) then there
is no need to launch pg_activate_logical_decoding(), until....:

The user decides to drop the logical slot on the primary, and then:

- If the slot is not the last logical slot, that's fine, drop it
- If the slot is the last logical one AND the user did not set a new flag
"wal_level_action" to "say preserve" or "force downgrade" (in the drop command)
then the drop fails with an informative error message.

That way:

- pg_activate_logical_decoding() is needed only if there is not already a logical
slot on the primary
- the drop requires the user to think twice if this is the last logical slot
- we don't ask the user to create a logical slot if he does not want to use it
on the primary

Thoughts?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-20 04:18:47
Message-ID: CAJpy0uC=rJM25ZmUGBVOV8qmD9vaxATNYSt8S3748EbYWCC4RA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jun 19, 2025 at 2:30 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> I wonder if a way to address the concerns that we shared above is to use a
> mixed approach like:
>
> - Forget the immediately_reserve idea
> - If a user creates a logical slot then we automatically switch to wal_level =
> logical (if not already done): I think that's a nice user experience
> - *and* provide a new API pg_activate_logical_decoding(), if the user has no
> need to create a logical slot on the primary (wants to use the standby to offload
> all the logical decoding)
>
> So if the user also uses a logical slot on the primary (for real..) then there
> is no need to launch pg_activate_logical_decoding(), until....:
>
> The user decides to drop the logical slot on the primary, and then:
>
> - If the slot is not the last logical slot, that's fine, drop it
> - If the slot is the last logical one AND the user did not set a new flag
> "wal_level_action" to "say preserve" or "force downgrade" (in the drop command)
> then the drop fails with an informative error message.

Overall the plan sounds reasonable one. But we need to think if the
slot is dropped on primary as part of Drop Subscription on subscriber,
then how will the user convey the wal-level preserve option? Giving it
as part of subscription-cmd to preserve wal-level on primary might not
be a good idea.

thanks
Shveta


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-20 06:45:01
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Fri, Jun 20, 2025 at 09:48:47AM +0530, shveta malik wrote:
> On Thu, Jun 19, 2025 at 2:30 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > I wonder if a way to address the concerns that we shared above is to use a
> > mixed approach like:
> >
> > - Forget the immediately_reserve idea
> > - If a user creates a logical slot then we automatically switch to wal_level =
> > logical (if not already done): I think that's a nice user experience
> > - *and* provide a new API pg_activate_logical_decoding(), if the user has no
> > need to create a logical slot on the primary (wants to use the standby to offload
> > all the logical decoding)
> >
> > So if the user also uses a logical slot on the primary (for real..) then there
> > is no need to launch pg_activate_logical_decoding(), until....:
> >
> > The user decides to drop the logical slot on the primary, and then:
> >
> > - If the slot is not the last logical slot, that's fine, drop it
> > - If the slot is the last logical one AND the user did not set a new flag
> > "wal_level_action" to "say preserve" or "force downgrade" (in the drop command)
> > then the drop fails with an informative error message.
>
> Overall the plan sounds reasonable one.

Thanks for sharing your thoughts!

> But we need to think if the
> slot is dropped on primary as part of Drop Subscription on subscriber,
> then how will the user convey the wal-level preserve option?

If the drop subscription attempts to drop the last logical replication slot
on the primary then it will fail. The "DROP SUBSCRIPTION" doc states:

"
To proceed in this situation, first disable the subscription by executing
ALTER SUBSCRIPTION ... DISABLE, and then disassociate it from the replication slot
by executing ALTER SUBSCRIPTION ... SET (slot_name = NONE).

After that, DROP SUBSCRIPTION will no longer attempt any actions on a remote host.
Note that if the remote replication slot still exists, it (and any related table
synchronization slots) should then be dropped manually; otherwise it/they will
continue to reserve WAL and might eventually cause the disk to fill up.
"

So one option is to drop the logical replication slot manually (providing a valid
wal_level_action value).

That's not the most elegant solution but if the error message is clear enough
(that this is the last logical replication slot and that it has to be
removed manually) that's "doable" to reach a clean state on the publisher
and subscriber sides.

> Giving it
> as part of subscription-cmd to preserve wal-level on primary

Yeah, another option is to make "wal_level_action" part of the "DROP SUBSCRIPTION"
command. In that case a common scenario would be:

- first drop fails because the wal_level_action value has not been specified
- then try to drop again but this time specifying a wal_level_action value

> might not be a good idea.

Agree that it sounds kind of weird and I'm not sure that I like the idea of
giving the "wal level" on the primary control on the subscriber side.

Without it a typical scenario would be:

- drop fails
- ALTER SUBSCRIPTION <> disable
- drop the slot on the primary
- ALTER SUBSCRIPTION <> SET (slot_name = NONE)
- drop succeeds

and that might not be user friendly but it gives the wal level control on the
publisher side (and I think that's better).

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-23 08:10:37
Message-ID: CAD21AoA_ADPNR9U2jEemAi4gri6dj+E6ecUiL7+iC9mNzAbeig@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jun 19, 2025 at 6:00 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Wed, Jun 18, 2025 at 03:22:59PM +0530, shveta malik wrote:
> > On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > IIUC the idea is to "just" increase WAL level to 'logical' so that one could then
> > > be allowed to make use of logical decoding from the standby. The primary goal
> > > of logical decoding from standby is to move some load from the primay to
> > > the standby i.e we don't expect/want the logical slot to be used on the primary.
> > >
> > > So what about making sure that if a logical slot is created with immediately_reserve
> > > set to false then no one can use it? (That would ensure that WAL reservation
> > > will not happen).
> > >
> >
> > Another concern is ensuring that users actually create this slot. If
> > there is already an active subscription subscribed to the primary, the
> > effective_wal_level will be set to logical already, allowing logical
> > decoding on the standby to proceed without issue. In such a case, the
> > user might not bother to create additional slots (same as problem
> > described in [1])) and later may unintentionally end up making standby
> > slots unusable. Any ideas on how to ensure it?
>
> > > That said, we might also want to create another parameter name (than
> > > immediately_reserve) to better reflect this behavior (if we move that way).
> > >
> > > Thoughts?
> >
> > Or we could avoid exposing control of immediately_reserve to the user
> > altogether? Instead, we reserve a specific slot name and ensure that
> > it never reserves WAL in the future by preventing it from being
> > consumed under any circumstances (as you suggested).
>
> I wonder if a way to address the concerns that we shared above is to use a
> mixed approach like:
>
> - Forget the immediately_reserve idea
> - If a user creates a logical slot then we automatically switch to wal_level =
> logical (if not already done): I think that's a nice user experience
> - *and* provide a new API pg_activate_logical_decoding(), if the user has no
> need to create a logical slot on the primary (wants to use the standby to offload
> all the logical decoding)
>
> So if the user also uses a logical slot on the primary (for real..) then there
> is no need to launch pg_activate_logical_decoding(), until....:
>
> The user decides to drop the logical slot on the primary, and then:
>
> - If the slot is not the last logical slot, that's fine, drop it
> - If the slot is the last logical one AND the user did not set a new flag
> "wal_level_action" to "say preserve" or "force downgrade" (in the drop command)
> then the drop fails with an informative error message.
>
> That way:
>
> - pg_activate_logical_decoding() is needed only if there is not already a logical
> slot on the primary
> - the drop requires the user to think twice if this is the last logical slot
> - we don't ask the user to create a logical slot if he does not want to use it
> on the primary
>
> Thoughts?

If there is no logical slot on the primary, how can the user disable
logical decoding that has been enabled via
pg_activate_logical_decoding()?

Given the discussion so far, it seems we might want to have a
safeguard to prevent the effective_wal_level from being dropped to
'replica' if the last logical slot is accidentally dropped. Another
idea we can consider is that we automatically increase
effective_wal_level to 'logical' upon the logical slot creation but
don't automatically decrease it when dropping the last slot. To
decrease the effective_wal_level to 'replica', users would need to do
that explicitly for example using a SQL function,
pg_disable_logical_decoding(). We might want to have a GUC parameter
for users to turn on/off this automatic behavior.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-23 09:19:22
Message-ID: CAJpy0uCNfmqi6MPv1VhAsw+HxjBM3Y+z8nvzGxurPV_xVE8V3A@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jun 20, 2025 at 12:15 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Fri, Jun 20, 2025 at 09:48:47AM +0530, shveta malik wrote:
> > On Thu, Jun 19, 2025 at 2:30 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > I wonder if a way to address the concerns that we shared above is to use a
> > > mixed approach like:
> > >
> > > - Forget the immediately_reserve idea
> > > - If a user creates a logical slot then we automatically switch to wal_level =
> > > logical (if not already done): I think that's a nice user experience
> > > - *and* provide a new API pg_activate_logical_decoding(), if the user has no
> > > need to create a logical slot on the primary (wants to use the standby to offload
> > > all the logical decoding)
> > >
> > > So if the user also uses a logical slot on the primary (for real..) then there
> > > is no need to launch pg_activate_logical_decoding(), until....:
> > >
> > > The user decides to drop the logical slot on the primary, and then:
> > >
> > > - If the slot is not the last logical slot, that's fine, drop it
> > > - If the slot is the last logical one AND the user did not set a new flag
> > > "wal_level_action" to "say preserve" or "force downgrade" (in the drop command)
> > > then the drop fails with an informative error message.
> >
> > Overall the plan sounds reasonable one.
>
> Thanks for sharing your thoughts!
>
> > But we need to think if the
> > slot is dropped on primary as part of Drop Subscription on subscriber,
> > then how will the user convey the wal-level preserve option?
>
> If the drop subscription attempts to drop the last logical replication slot
> on the primary then it will fail. The "DROP SUBSCRIPTION" doc states:
>
> "
> To proceed in this situation, first disable the subscription by executing
> ALTER SUBSCRIPTION ... DISABLE, and then disassociate it from the replication slot
> by executing ALTER SUBSCRIPTION ... SET (slot_name = NONE).
>
> After that, DROP SUBSCRIPTION will no longer attempt any actions on a remote host.
> Note that if the remote replication slot still exists, it (and any related table
> synchronization slots) should then be dropped manually; otherwise it/they will
> continue to reserve WAL and might eventually cause the disk to fill up.
> "
>
> So one option is to drop the logical replication slot manually (providing a valid
> wal_level_action value).
>
> That's not the most elegant solution but if the error message is clear enough
> (that this is the last logical replication slot and that it has to be
> removed manually) that's "doable" to reach a clean state on the publisher
> and subscriber sides.
>
> > Giving it
> > as part of subscription-cmd to preserve wal-level on primary
>
> Yeah, another option is to make "wal_level_action" part of the "DROP SUBSCRIPTION"
> command. In that case a common scenario would be:
>
> - first drop fails because the wal_level_action value has not been specified
> - then try to drop again but this time specifying a wal_level_action value
>
> > might not be a good idea.
>
> Agree that it sounds kind of weird and I'm not sure that I like the idea of
> giving the "wal level" on the primary control on the subscriber side.
>
> Without it a typical scenario would be:
>
> - drop fails
> - ALTER SUBSCRIPTION <> disable
> - drop the slot on the primary
> - ALTER SUBSCRIPTION <> SET (slot_name = NONE)
> - drop succeeds
>
> and that might not be user friendly but it gives the wal level control on the
> publisher side (and I think that's better).
>

I still feel that to switch wal_level automatically on primary, having
changes in subscription commands/steps might not be a good idea. The
acceptance of this idea could be lesser.

thanks
Shveta


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-23 10:01:40
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Mon, Jun 23, 2025 at 05:10:37PM +0900, Masahiko Sawada wrote:
> On Thu, Jun 19, 2025 at 6:00 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > - pg_activate_logical_decoding() is needed only if there is not already a logical
> > slot on the primary
> > - the drop requires the user to think twice if this is the last logical slot
> > - we don't ask the user to create a logical slot if he does not want to use it
> > on the primary
> >
> > Thoughts?
>
> If there is no logical slot on the primary, how can the user disable
> logical decoding that has been enabled via
> pg_activate_logical_decoding()?

I was thinking to keep the pg_deactivate_logical_decoding() API proposed
in this thread.

> Given the discussion so far, it seems we might want to have a
> safeguard to prevent the effective_wal_level from being dropped to
> 'replica' if the last logical slot is accidentally dropped. Another
> idea we can consider is that we automatically increase
> effective_wal_level to 'logical' upon the logical slot creation but
> don't automatically decrease it when dropping the last slot. To
> decrease the effective_wal_level to 'replica', users would need to do
> that explicitly for example using a SQL function,
> pg_disable_logical_decoding().

Yeah that could be an idea (and then we don't add the new wal_level_action
to the drop slot command).

> We might want to have a GUC parameter
> for users to turn on/off this automatic behavior.

You mean a GUC to both automaticly set effective_wal_level to logical at slot creation
and also decrease effective_wal_level to replica if last replication slot is dropped?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-23 10:02:42
Message-ID: CAJpy0uCAYbnMhL++LjKgG=Xc15oZy+HfdQE1zYVCDCDxbOEd3g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jun 23, 2025 at 1:41 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Given the discussion so far, it seems we might want to have a
> safeguard to prevent the effective_wal_level from being dropped to
> 'replica' if the last logical slot is accidentally dropped.

Yes, needed for cases where standby or cascaded standbys have
requirements of logical decoding.

> Another
> idea we can consider is that we automatically increase
> effective_wal_level to 'logical' upon the logical slot creation but
> don't automatically decrease it when dropping the last slot. To
> decrease the effective_wal_level to 'replica', users would need to do
> that explicitly for example using a SQL function,
> pg_disable_logical_decoding().

Okay. Seems a good solution so far.

> We might want to have a GUC parameter
> for users to turn on/off this automatic behavior.
>

Yes. Agreed.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-23 15:13:32
Message-ID: CAD21AoBwLqZ3ORSN8vRyZgr+Yt7rd1mQ=-f1bg355DweGePHGw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jun 23, 2025 at 7:01 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Mon, Jun 23, 2025 at 05:10:37PM +0900, Masahiko Sawada wrote:
> > On Thu, Jun 19, 2025 at 6:00 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > - pg_activate_logical_decoding() is needed only if there is not already a logical
> > > slot on the primary
> > > - the drop requires the user to think twice if this is the last logical slot
> > > - we don't ask the user to create a logical slot if he does not want to use it
> > > on the primary
> > >
> > > Thoughts?
> >
> > If there is no logical slot on the primary, how can the user disable
> > logical decoding that has been enabled via
> > pg_activate_logical_decoding()?
>
> I was thinking to keep the pg_deactivate_logical_decoding() API proposed
> in this thread.

Okay. One approach that combines your idea and Shveta's idea is:

- a special (empty) logical slot with the reserved slot name can be
created and deleted only by SQL functions,
pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
- this special slot cannot be used by logical decoding.
- effective_wal_level is increased and decreased when creating and
dropping a slot (i.e., either a normal logical slots or the special
logical slot).

That way, users who enabled the logical decoding via
pg_activate_logical_decoding() can keep the effective_wal_level being
'logical' since the special slot remains unless executes
pg_deactivate_logical_decoding(). And users who don't use these new
APIs can enable and disable the logical decoding at normal logical
slot creation and deletion.

>
> > Given the discussion so far, it seems we might want to have a
> > safeguard to prevent the effective_wal_level from being dropped to
> > 'replica' if the last logical slot is accidentally dropped. Another
> > idea we can consider is that we automatically increase
> > effective_wal_level to 'logical' upon the logical slot creation but
> > don't automatically decrease it when dropping the last slot. To
> > decrease the effective_wal_level to 'replica', users would need to do
> > that explicitly for example using a SQL function,
> > pg_disable_logical_decoding().
>
> Yeah that could be an idea (and then we don't add the new wal_level_action
> to the drop slot command).
>
> > We might want to have a GUC parameter
> > for users to turn on/off this automatic behavior.
>
> You mean a GUC to both automaticly set effective_wal_level to logical at slot creation
> and also decrease effective_wal_level to replica if last replication slot is dropped?

What I imagined was to control only the decreasing behavior that could
be more problematic than the increase case. But it might be rather
confusing (e.g., what if we turn off that behavior and restart the
server?).

Regards,

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


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-24 08:42:49
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Tue, Jun 24, 2025 at 12:13:32AM +0900, Masahiko Sawada wrote:
> On Mon, Jun 23, 2025 at 7:01 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > Hi,
> >
> > On Mon, Jun 23, 2025 at 05:10:37PM +0900, Masahiko Sawada wrote:
> > > On Thu, Jun 19, 2025 at 6:00 PM Bertrand Drouvot
> > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > >
> > > > - pg_activate_logical_decoding() is needed only if there is not already a logical
> > > > slot on the primary
> > > > - the drop requires the user to think twice if this is the last logical slot
> > > > - we don't ask the user to create a logical slot if he does not want to use it
> > > > on the primary
> > > >
> > > > Thoughts?
> > >
> > > If there is no logical slot on the primary, how can the user disable
> > > logical decoding that has been enabled via
> > > pg_activate_logical_decoding()?
> >
> > I was thinking to keep the pg_deactivate_logical_decoding() API proposed
> > in this thread.
>
> Okay. One approach that combines your idea and Shveta's idea is:
>
> - a special (empty) logical slot with the reserved slot name can be
> created and deleted only by SQL functions,
> pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> - this special slot cannot be used by logical decoding.
> - effective_wal_level is increased and decreased when creating and
> dropping a slot (i.e., either a normal logical slots or the special
> logical slot).

Yeah, I think that sounds reasonable and that would avoid users to use
the slot created with immediately_reserve set to false by mistake.

> > You mean a GUC to both automaticly set effective_wal_level to logical at slot creation
> > and also decrease effective_wal_level to replica if last replication slot is dropped?
>
> What I imagined was to control only the decreasing behavior that could
> be more problematic than the increase case. But it might be rather
> confusing (e.g., what if we turn off that behavior and restart the
> server?).

Right...So not sure we need such a GUC. What about always behave with the
automatic behavior?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-25 03:42:44
Message-ID: CAJpy0uCkrUVMZY6+xFd0iyBcK4PC_7_+V08k-ZQ7qL2w36iFmQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jun 24, 2025 at 2:12 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Tue, Jun 24, 2025 at 12:13:32AM +0900, Masahiko Sawada wrote:
> > On Mon, Jun 23, 2025 at 7:01 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > Hi,
> > >
> > > On Mon, Jun 23, 2025 at 05:10:37PM +0900, Masahiko Sawada wrote:
> > > > On Thu, Jun 19, 2025 at 6:00 PM Bertrand Drouvot
> > > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > >
> > > > > - pg_activate_logical_decoding() is needed only if there is not already a logical
> > > > > slot on the primary
> > > > > - the drop requires the user to think twice if this is the last logical slot
> > > > > - we don't ask the user to create a logical slot if he does not want to use it
> > > > > on the primary
> > > > >
> > > > > Thoughts?
> > > >
> > > > If there is no logical slot on the primary, how can the user disable
> > > > logical decoding that has been enabled via
> > > > pg_activate_logical_decoding()?
> > >
> > > I was thinking to keep the pg_deactivate_logical_decoding() API proposed
> > > in this thread.
> >
> > Okay. One approach that combines your idea and Shveta's idea is:
> >
> > - a special (empty) logical slot with the reserved slot name can be
> > created and deleted only by SQL functions,
> > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > - this special slot cannot be used by logical decoding.
> > - effective_wal_level is increased and decreased when creating and
> > dropping a slot (i.e., either a normal logical slots or the special
> > logical slot).
>
> Yeah, I think that sounds reasonable and that would avoid users to use
> the slot created with immediately_reserve set to false by mistake.
>

+1.
I think we do need to provide 'immediately_reserve' as a new argument
now for logical slots creation. If the slot is a special one with a
reserved name, it can internally be created with WALs not reserved for
our purpose.

> > > You mean a GUC to both automaticly set effective_wal_level to logical at slot creation
> > > and also decrease effective_wal_level to replica if last replication slot is dropped?
> >
> > What I imagined was to control only the decreasing behavior that could
> > be more problematic than the increase case. But it might be rather
> > confusing (e.g., what if we turn off that behavior and restart the
> > server?).
>
> Right...So not sure we need such a GUC. What about always behave with the
> automatic behavior?
>

Does it make sense to provide a GUC which will have the default set to
automatic but if the user is not interested or having some issues with
new behaviour, he can switch off the GUC, making the new functions
no-op as well?
In absence of such a GUC, users will have absolutely no way to switch
back to old behaviour. Will that be okay?

thanks
Shveta


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-25 03:45:04
Message-ID: CAJpy0uDuaj1DdDmqwbVpMd+XA62qjRqwgL=LP4RuaQ6vdMGBxA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 25, 2025 at 9:12 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Tue, Jun 24, 2025 at 2:12 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > Hi,
> >
> > On Tue, Jun 24, 2025 at 12:13:32AM +0900, Masahiko Sawada wrote:
> > > On Mon, Jun 23, 2025 at 7:01 PM Bertrand Drouvot
> > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Mon, Jun 23, 2025 at 05:10:37PM +0900, Masahiko Sawada wrote:
> > > > > On Thu, Jun 19, 2025 at 6:00 PM Bertrand Drouvot
> > > > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > - pg_activate_logical_decoding() is needed only if there is not already a logical
> > > > > > slot on the primary
> > > > > > - the drop requires the user to think twice if this is the last logical slot
> > > > > > - we don't ask the user to create a logical slot if he does not want to use it
> > > > > > on the primary
> > > > > >
> > > > > > Thoughts?
> > > > >
> > > > > If there is no logical slot on the primary, how can the user disable
> > > > > logical decoding that has been enabled via
> > > > > pg_activate_logical_decoding()?
> > > >
> > > > I was thinking to keep the pg_deactivate_logical_decoding() API proposed
> > > > in this thread.
> > >
> > > Okay. One approach that combines your idea and Shveta's idea is:
> > >
> > > - a special (empty) logical slot with the reserved slot name can be
> > > created and deleted only by SQL functions,
> > > pg_activate_logical_decoding() and pg_deactivate_logical_decoding().
> > > - this special slot cannot be used by logical decoding.
> > > - effective_wal_level is increased and decreased when creating and
> > > dropping a slot (i.e., either a normal logical slots or the special
> > > logical slot).
> >
> > Yeah, I think that sounds reasonable and that would avoid users to use
> > the slot created with immediately_reserve set to false by mistake.
> >
>
> +1.
> I think we do need to provide 'immediately_reserve' as a new argument
> now for logical slots creation. If the slot is a special one with a
> reserved name, it can internally be created with WALs not reserved for
> our purpose.
>

One correction here.
I think we do NOT need to provide 'immediately_reserve' as a new
argument now for logical slots creation. ...

> > > > You mean a GUC to both automaticly set effective_wal_level to logical at slot creation
> > > > and also decrease effective_wal_level to replica if last replication slot is dropped?
> > >
> > > What I imagined was to control only the decreasing behavior that could
> > > be more problematic than the increase case. But it might be rather
> > > confusing (e.g., what if we turn off that behavior and restart the
> > > server?).
> >
> > Right...So not sure we need such a GUC. What about always behave with the
> > automatic behavior?
> >
>
> Does it make sense to provide a GUC which will have the default set to
> automatic but if the user is not interested or having some issues with
> new behaviour, he can switch off the GUC, making the new functions
> no-op as well?
> In absence of such a GUC, users will have absolutely no way to switch
> back to old behaviour. Will that be okay?
>
> thanks
> Shveta


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-25 06:50:50
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Wed, Jun 25, 2025 at 09:15:04AM +0530, shveta malik wrote:
> On Wed, Jun 25, 2025 at 9:12 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Tue, Jun 24, 2025 at 2:12 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > Yeah, I think that sounds reasonable and that would avoid users to use
> > > the slot created with immediately_reserve set to false by mistake.
> > >
> >
> > +1.
> > I think we do need to provide 'immediately_reserve' as a new argument
> > now for logical slots creation. If the slot is a special one with a
> > reserved name, it can internally be created with WALs not reserved for
> > our purpose.
> >
>
> One correction here.
> I think we do NOT need to provide 'immediately_reserve' as a new
> argument now for logical slots creation. ...

Agree.

> > > Right...So not sure we need such a GUC. What about always behave with the
> > > automatic behavior?
> > >
> >
> > Does it make sense to provide a GUC which will have the default set to
> > automatic but if the user is not interested or having some issues with
> > new behaviour, he can switch off the GUC, making the new functions
> > no-op as well?
> > In absence of such a GUC, users will have absolutely no way to switch
> > back to old behaviour. Will that be okay?

Since it will be possible to switch back to logical without a restart I do
think that it could make sense to avoid a new GUC. Unless there is a use case
to keep the wal level to logical (outside of the "logical decoding from
standby" context)?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-26 08:50:02
Message-ID: CAJpy0uC6zz3xgMgsbSBtt2ue9tE1TsUJGXNeoDSpB6E4pD6s8Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 25, 2025 at 12:20 PM Bertrand Drouvot
<bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Wed, Jun 25, 2025 at 09:15:04AM +0530, shveta malik wrote:
> > On Wed, Jun 25, 2025 at 9:12 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Tue, Jun 24, 2025 at 2:12 PM Bertrand Drouvot
> > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > >
> > > > Yeah, I think that sounds reasonable and that would avoid users to use
> > > > the slot created with immediately_reserve set to false by mistake.
> > > >
> > >
> > > +1.
> > > I think we do need to provide 'immediately_reserve' as a new argument
> > > now for logical slots creation. If the slot is a special one with a
> > > reserved name, it can internally be created with WALs not reserved for
> > > our purpose.
> > >
> >
> > One correction here.
> > I think we do NOT need to provide 'immediately_reserve' as a new
> > argument now for logical slots creation. ...
>
> Agree.
>
> > > > Right...So not sure we need such a GUC. What about always behave with the
> > > > automatic behavior?
> > > >
> > >
> > > Does it make sense to provide a GUC which will have the default set to
> > > automatic but if the user is not interested or having some issues with
> > > new behaviour, he can switch off the GUC, making the new functions
> > > no-op as well?
> > > In absence of such a GUC, users will have absolutely no way to switch
> > > back to old behaviour. Will that be okay?
>
> Since it will be possible to switch back to logical without a restart I do
> think that it could make sense to avoid a new GUC. Unless there is a use case
> to keep the wal level to logical (outside of the "logical decoding from
> standby" context)?
>

I don’t currently see a specific use case for this, but I’m somewhat
inclined to include the GUC because it can serve as a safety
mechanism. If issues arise with the new behavior, the GUC allows users
to revert to manually controlling wal_level. The GUC would only manage
the automatic aspect of the feature, where slot creation and deletion
internally adjust wal_level. But I don’t have a strong preference and
am open to omitting the GUC if others believe it is unnecessary.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-30 05:45:37
Message-ID: CAD21AoA0c+-j0FbAhpEWFCnsPBv6a1KBaSeswhi2nH50gSNpdw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jun 26, 2025 at 5:50 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jun 25, 2025 at 12:20 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > Hi,
> >
> > On Wed, Jun 25, 2025 at 09:15:04AM +0530, shveta malik wrote:
> > > On Wed, Jun 25, 2025 at 9:12 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > >
> > > > On Tue, Jun 24, 2025 at 2:12 PM Bertrand Drouvot
> > > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > >
> > > > > Yeah, I think that sounds reasonable and that would avoid users to use
> > > > > the slot created with immediately_reserve set to false by mistake.
> > > > >
> > > >
> > > > +1.
> > > > I think we do need to provide 'immediately_reserve' as a new argument
> > > > now for logical slots creation. If the slot is a special one with a
> > > > reserved name, it can internally be created with WALs not reserved for
> > > > our purpose.
> > > >
> > >
> > > One correction here.
> > > I think we do NOT need to provide 'immediately_reserve' as a new
> > > argument now for logical slots creation. ...
> >
> > Agree.

Agreed.

> >
> > > > > Right...So not sure we need such a GUC. What about always behave with the
> > > > > automatic behavior?
> > > > >
> > > >
> > > > Does it make sense to provide a GUC which will have the default set to
> > > > automatic but if the user is not interested or having some issues with
> > > > new behaviour, he can switch off the GUC, making the new functions
> > > > no-op as well?
> > > > In absence of such a GUC, users will have absolutely no way to switch
> > > > back to old behaviour. Will that be okay?
> >
> > Since it will be possible to switch back to logical without a restart I do
> > think that it could make sense to avoid a new GUC. Unless there is a use case
> > to keep the wal level to logical (outside of the "logical decoding from
> > standby" context)?
> >
>
> I don’t currently see a specific use case for this, but I’m somewhat
> inclined to include the GUC because it can serve as a safety
> mechanism. If issues arise with the new behavior, the GUC allows users
> to revert to manually controlling wal_level. The GUC would only manage
> the automatic aspect of the feature, where slot creation and deletion
> internally adjust wal_level. But I don’t have a strong preference and
> am open to omitting the GUC if others believe it is unnecessary.

I think the new SQL API to enable the logical decoding would provide a
new way for users who want to enable the logical decoding for standbys
without creating a slot. With that, the user can enable/disable the
logical decoding by calling the SQL function. Also, it's not a
replacement of the current usage (i.e., changing wal_level with
restarting the server). The GUC parameter we're discussing sounds like
a way to serve the current behavior that allows users to
enable/disable the logical decoding only with restarting the server.
I'm not sure if there are users who want to disable the new behavior
and use only the current behavior. I think we can focus on the new API
and automatic behavior at this stage. If we find out there are certain
use cases, we can revisit this idea.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-30 06:51:44
Message-ID: CAJpy0uAFC68439c9nCp1hZkwM26eSPYG5ByX4UQxWiFufaXr4g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jun 30, 2025 at 11:16 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Jun 26, 2025 at 5:50 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 25, 2025 at 12:20 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > Hi,
> > >
> > > On Wed, Jun 25, 2025 at 09:15:04AM +0530, shveta malik wrote:
> > > > On Wed, Jun 25, 2025 at 9:12 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Tue, Jun 24, 2025 at 2:12 PM Bertrand Drouvot
> > > > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > Yeah, I think that sounds reasonable and that would avoid users to use
> > > > > > the slot created with immediately_reserve set to false by mistake.
> > > > > >
> > > > >
> > > > > +1.
> > > > > I think we do need to provide 'immediately_reserve' as a new argument
> > > > > now for logical slots creation. If the slot is a special one with a
> > > > > reserved name, it can internally be created with WALs not reserved for
> > > > > our purpose.
> > > > >
> > > >
> > > > One correction here.
> > > > I think we do NOT need to provide 'immediately_reserve' as a new
> > > > argument now for logical slots creation. ...
> > >
> > > Agree.
>
> Agreed.
>
> > >
> > > > > > Right...So not sure we need such a GUC. What about always behave with the
> > > > > > automatic behavior?
> > > > > >
> > > > >
> > > > > Does it make sense to provide a GUC which will have the default set to
> > > > > automatic but if the user is not interested or having some issues with
> > > > > new behaviour, he can switch off the GUC, making the new functions
> > > > > no-op as well?
> > > > > In absence of such a GUC, users will have absolutely no way to switch
> > > > > back to old behaviour. Will that be okay?
> > >
> > > Since it will be possible to switch back to logical without a restart I do
> > > think that it could make sense to avoid a new GUC. Unless there is a use case
> > > to keep the wal level to logical (outside of the "logical decoding from
> > > standby" context)?
> > >
> >
> > I don’t currently see a specific use case for this, but I’m somewhat
> > inclined to include the GUC because it can serve as a safety
> > mechanism. If issues arise with the new behavior, the GUC allows users
> > to revert to manually controlling wal_level. The GUC would only manage
> > the automatic aspect of the feature, where slot creation and deletion
> > internally adjust wal_level. But I don’t have a strong preference and
> > am open to omitting the GUC if others believe it is unnecessary.
>
> I think the new SQL API to enable the logical decoding would provide a
> new way for users who want to enable the logical decoding for standbys
> without creating a slot. With that, the user can enable/disable the
> logical decoding by calling the SQL function. Also, it's not a
> replacement of the current usage (i.e., changing wal_level with
> restarting the server). The GUC parameter we're discussing sounds like
> a way to serve the current behavior that allows users to
> enable/disable the logical decoding only with restarting the server.
> I'm not sure if there are users who want to disable the new behavior
> and use only the current behavior. I think we can focus on the new API
> and automatic behavior at this stage. If we find out there are certain
> use cases, we can revisit this idea.
>

Okay, sounds good to me.

thanks
Shveta


From: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-06-30 13:41:04
Message-ID: [email protected]
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

On Mon, Jun 30, 2025 at 12:21:44PM +0530, shveta malik wrote:
> On Mon, Jun 30, 2025 at 11:16 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > I'm not sure if there are users who want to disable the new behavior
> > and use only the current behavior. I think we can focus on the new API
> > and automatic behavior at this stage. If we find out there are certain
> > use cases, we can revisit this idea.
> >
>
> Okay, sounds good to me.

Same here.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-02 16:15:32
Message-ID: CAD21AoA=5JMx+PnOQn5v2=_pNvYewON0i+7_gBNaC=pa8MFp5A@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 18, 2025 at 1:07 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jun 18, 2025 at 6:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > Thank you for the comments!
> >
> > >
> > > 2)
> > > I see that when primary switches back its effective wal_level to
> > > replica while standby has wal_level=logical in conf file, then standby
> > > has this status:
> > >
> > > postgres=# show wal_level;
> > > wal_level
> > > -----------
> > > logical
> > >
> > > postgres=# show effective_wal_level;
> > > effective_wal_level
> > > ---------------------
> > > replica
> > >
> > > Is this correct? Can effective_wal_level be < wal_level anytime? I
> > > feel it can be greater but never lesser.
> >
> > Hmm, I think we need to define what value we should show in
> > effective_wal_level on standbys because the standbys actually are not
> > writing any WALs and whether or not the logical decoding is enabled on
> > the standbys depends on the primary.
> >
> > In the previous version patch, the standby's effective_wal_level value
> > depended solely on the standby's wal_level value. However, it was
> > confusing in a sense because it's possible that the logical decoding
> > could be available even though effective_wal_level is 'replica' if the
> > primary already enables it. One idea is that given that the logical
> > decoding availability and effective_wal_level value are independent in
> > principle, it's better to provide a SQL function to get the logical
> > decoding status so that users can check the logical decoding
> > availability without checking effective_wal_level. With that function,
> > it might make sense to revert back the behavior to the previous one.
> > That is, on the primary the effective_wal_level value is always
> > greater than or equal to wal_level whereas on the standbys it's always
> > the same as wal_level, and users would be able to check the logical
> > decoding availability using the SQL function. Or it might also be
> > worth considering to show effective_wal_level as NULL on standbys.
>
> Yes, that is one idea. It will resolve the confusion.
> But I was thinking, instead of having one new GUC + a SQL function,
> can we have a GUC alone, which shows logical_decoding status plus the
> cause of that. The new GUC will be applicable on both primary and
> standby. As an example, let's say we name it as
> logical_decoding_status, then it can have these values (
> <status>_<cause>):
>
> enabled_wal_level_logical: valid both
> for primary, standby
> enabled_effective_wal_level_logical: valid only for primary
> enabled_cascaded_logical_decoding valid only for standby
> disabled :
> valid both for primary, standby
>
> 'enabled_cascaded_logical_decoding' will indicate that logical
> decoding is enabled on standby (even when its own wal_level=replica)
> as a cascaded effect from primary. It can be possible either due to
> primary's wal_level=logical or logical slot being present on primary.

I'm not sure it's a good idea to combine two values into one GUC
because the tools would have to parse the string in order to know when
they want to know either information.

As for the effective_wal_level shown on the standby, if it shows the
effective WAL level it might make sense to show as 'replica' even if
the standby's wal_level is 'logical' because the standby cannot write
any WAL and need to follow the primary. While it might be worth
considering to accept the case of effective_wal_level (replica) <
wal_level (logical) only on the standbys, we need to keep the
principle that the logical decoding is available only when
effective_wal_level = 'logical'.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-03 06:32:43
Message-ID: CAJpy0uCWVzNrFya=8uA4SyU6JTA0B_Kr-WGHRe+HLj4=RaoitA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jul 2, 2025 at 9:46 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Wed, Jun 18, 2025 at 1:07 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 18, 2025 at 6:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > Thank you for the comments!
> > >
> > > >
> > > > 2)
> > > > I see that when primary switches back its effective wal_level to
> > > > replica while standby has wal_level=logical in conf file, then standby
> > > > has this status:
> > > >
> > > > postgres=# show wal_level;
> > > > wal_level
> > > > -----------
> > > > logical
> > > >
> > > > postgres=# show effective_wal_level;
> > > > effective_wal_level
> > > > ---------------------
> > > > replica
> > > >
> > > > Is this correct? Can effective_wal_level be < wal_level anytime? I
> > > > feel it can be greater but never lesser.
> > >
> > > Hmm, I think we need to define what value we should show in
> > > effective_wal_level on standbys because the standbys actually are not
> > > writing any WALs and whether or not the logical decoding is enabled on
> > > the standbys depends on the primary.
> > >
> > > In the previous version patch, the standby's effective_wal_level value
> > > depended solely on the standby's wal_level value. However, it was
> > > confusing in a sense because it's possible that the logical decoding
> > > could be available even though effective_wal_level is 'replica' if the
> > > primary already enables it. One idea is that given that the logical
> > > decoding availability and effective_wal_level value are independent in
> > > principle, it's better to provide a SQL function to get the logical
> > > decoding status so that users can check the logical decoding
> > > availability without checking effective_wal_level. With that function,
> > > it might make sense to revert back the behavior to the previous one.
> > > That is, on the primary the effective_wal_level value is always
> > > greater than or equal to wal_level whereas on the standbys it's always
> > > the same as wal_level, and users would be able to check the logical
> > > decoding availability using the SQL function. Or it might also be
> > > worth considering to show effective_wal_level as NULL on standbys.
> >
> > Yes, that is one idea. It will resolve the confusion.
> > But I was thinking, instead of having one new GUC + a SQL function,
> > can we have a GUC alone, which shows logical_decoding status plus the
> > cause of that. The new GUC will be applicable on both primary and
> > standby. As an example, let's say we name it as
> > logical_decoding_status, then it can have these values (
> > <status>_<cause>):
> >
> > enabled_wal_level_logical: valid both
> > for primary, standby
> > enabled_effective_wal_level_logical: valid only for primary
> > enabled_cascaded_logical_decoding valid only for standby
> > disabled :
> > valid both for primary, standby
> >
> > 'enabled_cascaded_logical_decoding' will indicate that logical
> > decoding is enabled on standby (even when its own wal_level=replica)
> > as a cascaded effect from primary. It can be possible either due to
> > primary's wal_level=logical or logical slot being present on primary.
>
> I'm not sure it's a good idea to combine two values into one GUC
> because the tools would have to parse the string in order to know when
> they want to know either information.

Okay. Agreed.

> As for the effective_wal_level shown on the standby, if it shows the
> effective WAL level it might make sense to show as 'replica' even if
> the standby's wal_level is 'logical'

Alright. It depends on the definition we choose to assign to
effective_wal_level.

> because the standby cannot write
> any WAL and need to follow the primary.

When the standby’s wal_level is set to 'logical', the requirement for
logical decoding is already fulfilled. Or do you mean that the
effective_wal_level on standby should not be shown as logical until
both the primary and standby have wal_level set to logical and we also
have a logical slot present on standby?

> While it might be worth
> considering to accept the case of effective_wal_level (replica) <
> wal_level (logical) only on the standbys, we need to keep the
> principle that the logical decoding is available only when
> effective_wal_level = 'logical'.
>

Back to the previous question, when will the effective_wal_level be
displayed as 'logical' on standby? Which criterias need to be met?

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-06 15:03:05
Message-ID: CAD21AoB6=QtcEQ9c41c6OHprbH=3AY__ZntBm+2EPicbMBrQPg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jul 3, 2025 at 3:32 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jul 2, 2025 at 9:46 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 18, 2025 at 1:07 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jun 18, 2025 at 6:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > Thank you for the comments!
> > > >
> > > > >
> > > > > 2)
> > > > > I see that when primary switches back its effective wal_level to
> > > > > replica while standby has wal_level=logical in conf file, then standby
> > > > > has this status:
> > > > >
> > > > > postgres=# show wal_level;
> > > > > wal_level
> > > > > -----------
> > > > > logical
> > > > >
> > > > > postgres=# show effective_wal_level;
> > > > > effective_wal_level
> > > > > ---------------------
> > > > > replica
> > > > >
> > > > > Is this correct? Can effective_wal_level be < wal_level anytime? I
> > > > > feel it can be greater but never lesser.
> > > >
> > > > Hmm, I think we need to define what value we should show in
> > > > effective_wal_level on standbys because the standbys actually are not
> > > > writing any WALs and whether or not the logical decoding is enabled on
> > > > the standbys depends on the primary.
> > > >
> > > > In the previous version patch, the standby's effective_wal_level value
> > > > depended solely on the standby's wal_level value. However, it was
> > > > confusing in a sense because it's possible that the logical decoding
> > > > could be available even though effective_wal_level is 'replica' if the
> > > > primary already enables it. One idea is that given that the logical
> > > > decoding availability and effective_wal_level value are independent in
> > > > principle, it's better to provide a SQL function to get the logical
> > > > decoding status so that users can check the logical decoding
> > > > availability without checking effective_wal_level. With that function,
> > > > it might make sense to revert back the behavior to the previous one.
> > > > That is, on the primary the effective_wal_level value is always
> > > > greater than or equal to wal_level whereas on the standbys it's always
> > > > the same as wal_level, and users would be able to check the logical
> > > > decoding availability using the SQL function. Or it might also be
> > > > worth considering to show effective_wal_level as NULL on standbys.
> > >
> > > Yes, that is one idea. It will resolve the confusion.
> > > But I was thinking, instead of having one new GUC + a SQL function,
> > > can we have a GUC alone, which shows logical_decoding status plus the
> > > cause of that. The new GUC will be applicable on both primary and
> > > standby. As an example, let's say we name it as
> > > logical_decoding_status, then it can have these values (
> > > <status>_<cause>):
> > >
> > > enabled_wal_level_logical: valid both
> > > for primary, standby
> > > enabled_effective_wal_level_logical: valid only for primary
> > > enabled_cascaded_logical_decoding valid only for standby
> > > disabled :
> > > valid both for primary, standby
> > >
> > > 'enabled_cascaded_logical_decoding' will indicate that logical
> > > decoding is enabled on standby (even when its own wal_level=replica)
> > > as a cascaded effect from primary. It can be possible either due to
> > > primary's wal_level=logical or logical slot being present on primary.
> >
> > I'm not sure it's a good idea to combine two values into one GUC
> > because the tools would have to parse the string in order to know when
> > they want to know either information.
>
> Okay. Agreed.
>
> > As for the effective_wal_level shown on the standby, if it shows the
> > effective WAL level it might make sense to show as 'replica' even if
> > the standby's wal_level is 'logical'
>
> Alright. It depends on the definition we choose to assign to
> effective_wal_level.
>
> > because the standby cannot write
> > any WAL and need to follow the primary.
>
> When the standby’s wal_level is set to 'logical', the requirement for
> logical decoding is already fulfilled. Or do you mean that the
> effective_wal_level on standby should not be shown as logical until
> both the primary and standby have wal_level set to logical and we also
> have a logical slot present on standby?

Even when the standby's wal_level is 'logical', the logical decoding
cannot be used on the standby if the primary doesn't enable it. IOW,
even if the standby's wal_level is 'replica', the logical decoding is
available on the standby if the primary enables it.

>
> > While it might be worth
> > considering to accept the case of effective_wal_level (replica) <
> > wal_level (logical) only on the standbys, we need to keep the
> > principle that the logical decoding is available only when
> > effective_wal_level = 'logical'.
> >
>
> Back to the previous question, when will the effective_wal_level be
> displayed as 'logical' on standby? Which criterias need to be met?

The criteria is whether the primary enables the logical decoding or
not. If the primary enables the logical decoding by either setting
wal_level='logical' or creating a logical slot, the
effective_wal_level on the standby will be displayed as 'logical'.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-08 10:41:19
Message-ID: CAJpy0uDtd-73wXJocJrsgt0rVqG8RSvoSRH+wU_QWFu7py9+Wg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, Jul 6, 2025 at 8:33 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Jul 3, 2025 at 3:32 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jul 2, 2025 at 9:46 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jun 18, 2025 at 1:07 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Jun 18, 2025 at 6:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > >
> > > > > Thank you for the comments!
> > > > >
> > > > > >
> > > > > > 2)
> > > > > > I see that when primary switches back its effective wal_level to
> > > > > > replica while standby has wal_level=logical in conf file, then standby
> > > > > > has this status:
> > > > > >
> > > > > > postgres=# show wal_level;
> > > > > > wal_level
> > > > > > -----------
> > > > > > logical
> > > > > >
> > > > > > postgres=# show effective_wal_level;
> > > > > > effective_wal_level
> > > > > > ---------------------
> > > > > > replica
> > > > > >
> > > > > > Is this correct? Can effective_wal_level be < wal_level anytime? I
> > > > > > feel it can be greater but never lesser.
> > > > >
> > > > > Hmm, I think we need to define what value we should show in
> > > > > effective_wal_level on standbys because the standbys actually are not
> > > > > writing any WALs and whether or not the logical decoding is enabled on
> > > > > the standbys depends on the primary.
> > > > >
> > > > > In the previous version patch, the standby's effective_wal_level value
> > > > > depended solely on the standby's wal_level value. However, it was
> > > > > confusing in a sense because it's possible that the logical decoding
> > > > > could be available even though effective_wal_level is 'replica' if the
> > > > > primary already enables it. One idea is that given that the logical
> > > > > decoding availability and effective_wal_level value are independent in
> > > > > principle, it's better to provide a SQL function to get the logical
> > > > > decoding status so that users can check the logical decoding
> > > > > availability without checking effective_wal_level. With that function,
> > > > > it might make sense to revert back the behavior to the previous one.
> > > > > That is, on the primary the effective_wal_level value is always
> > > > > greater than or equal to wal_level whereas on the standbys it's always
> > > > > the same as wal_level, and users would be able to check the logical
> > > > > decoding availability using the SQL function. Or it might also be
> > > > > worth considering to show effective_wal_level as NULL on standbys.
> > > >
> > > > Yes, that is one idea. It will resolve the confusion.
> > > > But I was thinking, instead of having one new GUC + a SQL function,
> > > > can we have a GUC alone, which shows logical_decoding status plus the
> > > > cause of that. The new GUC will be applicable on both primary and
> > > > standby. As an example, let's say we name it as
> > > > logical_decoding_status, then it can have these values (
> > > > <status>_<cause>):
> > > >
> > > > enabled_wal_level_logical: valid both
> > > > for primary, standby
> > > > enabled_effective_wal_level_logical: valid only for primary
> > > > enabled_cascaded_logical_decoding valid only for standby
> > > > disabled :
> > > > valid both for primary, standby
> > > >
> > > > 'enabled_cascaded_logical_decoding' will indicate that logical
> > > > decoding is enabled on standby (even when its own wal_level=replica)
> > > > as a cascaded effect from primary. It can be possible either due to
> > > > primary's wal_level=logical or logical slot being present on primary.
> > >
> > > I'm not sure it's a good idea to combine two values into one GUC
> > > because the tools would have to parse the string in order to know when
> > > they want to know either information.
> >
> > Okay. Agreed.
> >
> > > As for the effective_wal_level shown on the standby, if it shows the
> > > effective WAL level it might make sense to show as 'replica' even if
> > > the standby's wal_level is 'logical'
> >
> > Alright. It depends on the definition we choose to assign to
> > effective_wal_level.
> >
> > > because the standby cannot write
> > > any WAL and need to follow the primary.
> >
> > When the standby’s wal_level is set to 'logical', the requirement for
> > logical decoding is already fulfilled. Or do you mean that the
> > effective_wal_level on standby should not be shown as logical until
> > both the primary and standby have wal_level set to logical and we also
> > have a logical slot present on standby?
>
> Even when the standby's wal_level is 'logical', the logical decoding
> cannot be used on the standby if the primary doesn't enable it. IOW,
> even if the standby's wal_level is 'replica', the logical decoding is
> available on the standby if the primary enables it.
>
> >
> > > While it might be worth
> > > considering to accept the case of effective_wal_level (replica) <
> > > wal_level (logical) only on the standbys, we need to keep the
> > > principle that the logical decoding is available only when
> > > effective_wal_level = 'logical'.
> > >
> >
> > Back to the previous question, when will the effective_wal_level be
> > displayed as 'logical' on standby? Which criterias need to be met?
>
> The criteria is whether the primary enables the logical decoding or
> not. If the primary enables the logical decoding by either setting
> wal_level='logical' or creating a logical slot, the
> effective_wal_level on the standby will be displayed as 'logical'.
>

Okay, I understand it now. Thanks for explaining. The proposed
behaviour looks reasonable.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-15 17:07:11
Message-ID: CAD21AoCFzgyRrQ9J-6T5Ed_3jz=FWnr4zHEu+=0QV3hu8Gd++w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jul 8, 2025 at 7:41 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Sun, Jul 6, 2025 at 8:33 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Thu, Jul 3, 2025 at 3:32 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jul 2, 2025 at 9:46 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Jun 18, 2025 at 1:07 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Wed, Jun 18, 2025 at 6:06 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > Thank you for the comments!
> > > > > >
> > > > > > >
> > > > > > > 2)
> > > > > > > I see that when primary switches back its effective wal_level to
> > > > > > > replica while standby has wal_level=logical in conf file, then standby
> > > > > > > has this status:
> > > > > > >
> > > > > > > postgres=# show wal_level;
> > > > > > > wal_level
> > > > > > > -----------
> > > > > > > logical
> > > > > > >
> > > > > > > postgres=# show effective_wal_level;
> > > > > > > effective_wal_level
> > > > > > > ---------------------
> > > > > > > replica
> > > > > > >
> > > > > > > Is this correct? Can effective_wal_level be < wal_level anytime? I
> > > > > > > feel it can be greater but never lesser.
> > > > > >
> > > > > > Hmm, I think we need to define what value we should show in
> > > > > > effective_wal_level on standbys because the standbys actually are not
> > > > > > writing any WALs and whether or not the logical decoding is enabled on
> > > > > > the standbys depends on the primary.
> > > > > >
> > > > > > In the previous version patch, the standby's effective_wal_level value
> > > > > > depended solely on the standby's wal_level value. However, it was
> > > > > > confusing in a sense because it's possible that the logical decoding
> > > > > > could be available even though effective_wal_level is 'replica' if the
> > > > > > primary already enables it. One idea is that given that the logical
> > > > > > decoding availability and effective_wal_level value are independent in
> > > > > > principle, it's better to provide a SQL function to get the logical
> > > > > > decoding status so that users can check the logical decoding
> > > > > > availability without checking effective_wal_level. With that function,
> > > > > > it might make sense to revert back the behavior to the previous one.
> > > > > > That is, on the primary the effective_wal_level value is always
> > > > > > greater than or equal to wal_level whereas on the standbys it's always
> > > > > > the same as wal_level, and users would be able to check the logical
> > > > > > decoding availability using the SQL function. Or it might also be
> > > > > > worth considering to show effective_wal_level as NULL on standbys.
> > > > >
> > > > > Yes, that is one idea. It will resolve the confusion.
> > > > > But I was thinking, instead of having one new GUC + a SQL function,
> > > > > can we have a GUC alone, which shows logical_decoding status plus the
> > > > > cause of that. The new GUC will be applicable on both primary and
> > > > > standby. As an example, let's say we name it as
> > > > > logical_decoding_status, then it can have these values (
> > > > > <status>_<cause>):
> > > > >
> > > > > enabled_wal_level_logical: valid both
> > > > > for primary, standby
> > > > > enabled_effective_wal_level_logical: valid only for primary
> > > > > enabled_cascaded_logical_decoding valid only for standby
> > > > > disabled :
> > > > > valid both for primary, standby
> > > > >
> > > > > 'enabled_cascaded_logical_decoding' will indicate that logical
> > > > > decoding is enabled on standby (even when its own wal_level=replica)
> > > > > as a cascaded effect from primary. It can be possible either due to
> > > > > primary's wal_level=logical or logical slot being present on primary.
> > > >
> > > > I'm not sure it's a good idea to combine two values into one GUC
> > > > because the tools would have to parse the string in order to know when
> > > > they want to know either information.
> > >
> > > Okay. Agreed.
> > >
> > > > As for the effective_wal_level shown on the standby, if it shows the
> > > > effective WAL level it might make sense to show as 'replica' even if
> > > > the standby's wal_level is 'logical'
> > >
> > > Alright. It depends on the definition we choose to assign to
> > > effective_wal_level.
> > >
> > > > because the standby cannot write
> > > > any WAL and need to follow the primary.
> > >
> > > When the standby’s wal_level is set to 'logical', the requirement for
> > > logical decoding is already fulfilled. Or do you mean that the
> > > effective_wal_level on standby should not be shown as logical until
> > > both the primary and standby have wal_level set to logical and we also
> > > have a logical slot present on standby?
> >
> > Even when the standby's wal_level is 'logical', the logical decoding
> > cannot be used on the standby if the primary doesn't enable it. IOW,
> > even if the standby's wal_level is 'replica', the logical decoding is
> > available on the standby if the primary enables it.
> >
> > >
> > > > While it might be worth
> > > > considering to accept the case of effective_wal_level (replica) <
> > > > wal_level (logical) only on the standbys, we need to keep the
> > > > principle that the logical decoding is available only when
> > > > effective_wal_level = 'logical'.
> > > >
> > >
> > > Back to the previous question, when will the effective_wal_level be
> > > displayed as 'logical' on standby? Which criterias need to be met?
> >
> > The criteria is whether the primary enables the logical decoding or
> > not. If the primary enables the logical decoding by either setting
> > wal_level='logical' or creating a logical slot, the
> > effective_wal_level on the standby will be displayed as 'logical'.
> >
>
> Okay, I understand it now. Thanks for explaining. The proposed
> behaviour looks reasonable.

I've attached updated patches that implement the idea we've discussed.
The patches still need to be polished but the implemented ideas seem
good. Feedback is very welcome.

Regards,

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

Attachment Content-Type Size
v3-0002-Add-pg_-de-activate_logical_decoding-SQL-function.patch application/octet-stream 15.1 KB
v3-0003-Add-regression-tests-for-online-logical-decoding-.patch application/octet-stream 9.8 KB
v3-0001-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 45.3 KB

From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-16 05:55:17
Message-ID: CAJpy0uC0e=J7L4q9RnQ3pbSAtvWy40r9qp3tr41zoogHQmDO8g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jul 15, 2025 at 10:37 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> I've attached updated patches that implement the idea we've discussed.
> The patches still need to be polished but the implemented ideas seem
> good. Feedback is very welcome.
>

Thank You for the patches. I just tried my hands on ptach001 yet, few concerns:

1)
+ else if (xlrec.wal_level == WAL_LEVEL_REPLICA &&
+ pg_atomic_read_u32(&ReplicationSlotCtl->n_inuse_logical_slots) == 0)
+ {
+ /*
+ * Disable the logical decoding if there is no in-use logical slot
+ * on the standby.
+ */
+ UpdateLogicalDecodingStatus(false);
+ }

Due to above logic, the change in wal_level to replica on primary may
end up disabling logical decoding on standby, even if logical decoding
is still enabled on primary due to existence of slot.

Steps:
a) Create a slot on primary, but no slots on standby.
b) Switch wal_level to logical on primary by doing a restart.
c) Now switch wal_level back to replica on primary. This will end up
disabling logical decoding on standby and slot creation will fail on
standby as well.

2)
In the same code, why don't we invalidate slots as we do when we
receive XLOG_LOGICAL_DECODING_STATUS_CHANGE?

3)
+ EnsureLogicalDecodingEnabled();

I do not understand the usage of above in synchronize_one_slot().
Since 'EnsureLogicalDecodingEnabled' is a no-op for standby, it will
do nothing here.

4)
- if (wal_level < WAL_LEVEL_LOGICAL)
- ereport(ERROR,
- errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("replication slot synchronization requires \"wal_level\" >=
\"logical\""));
+ if (!IsLogicalDecodingEnabled())
+ ereport(elevel,
+ errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+

Is the change from 'ERROR' to 'elevel' intentional? With this change,
slotsync worker will keep running even if logical decoding is not
enabled on standby (or primary) yet.

thanks
Shveta


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-17 09:36:04
Message-ID: CAA4eK1+KE-=d2oFLSOm_Z8FK94ZWW_X3Vta3vOd3gsNpB+WxkQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jun 18, 2025 at 3:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> >
> > Hi,
> >
> > On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> >
> > Thanks for the patch and sorry to be late in this conversation.
> >
> > The thing that worry me a bit with this is that that could be easy to attempt
> > to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> > by mistake on the primary. I think that this mistake is more likely to happen
> > with a logical slot as compared to a physical slot.
> >
>
> Yes, agreed. Another concern is the possibility of someone
> intentionally using it and associating it with a subscription. If the
> subscription is later dropped, it could also cause the slot to be
> removed.
>

IIUC, your main concern here is that the last slot on
primary/publisher could be dropped unintentionally by the user leading
to invalidating the logical slots on any physical-standby connected
with publisher, right?

What if we make DROP SUBSCRIPTION fail if it can lead to removal of
the last slot on publisher and allow DROP to succeed when the
subscription's drop_slot_force (a new subscription option) is set?
Now, users can still be allowed to Drop the subscription, if it
disassociates the subscription from the slot by using method explained
in docs [1] (See Notes section). Similarly when a user is trying to
drop the last logical slot via pg_drop_replication_slot, we will allow
it only with the force option. This should ensure that the user is
aware of the consequences of dropping the last slot.

--
With Regards,
Amit Kapila.


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-17 09:37:42
Message-ID: CAA4eK1+2c_fShnjj7x91G2Oh-2JK_auo9t4RymKhXFwBPtA8WA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jul 17, 2025 at 3:06 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Wed, Jun 18, 2025 at 3:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > >
> > > Thanks for the patch and sorry to be late in this conversation.
> > >
> > > The thing that worry me a bit with this is that that could be easy to attempt
> > > to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> > > by mistake on the primary. I think that this mistake is more likely to happen
> > > with a logical slot as compared to a physical slot.
> > >
> >
> > Yes, agreed. Another concern is the possibility of someone
> > intentionally using it and associating it with a subscription. If the
> > subscription is later dropped, it could also cause the slot to be
> > removed.
> >
>
> IIUC, your main concern here is that the last slot on
> primary/publisher could be dropped unintentionally by the user leading
> to invalidating the logical slots on any physical-standby connected
> with publisher, right?
>
> What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> the last slot on publisher and allow DROP to succeed when the
> subscription's drop_slot_force (a new subscription option) is set?
> Now, users can still be allowed to Drop the subscription, if it
> disassociates the subscription from the slot by using method explained
> in docs [1] (See Notes section).
>

Forgot to specify link. Done now [1].

[1] - https://www.postgresql.org/docs/devel/sql-dropsubscription.html

--
With Regards,
Amit Kapila.


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-17 18:55:30
Message-ID: CAD21AoD5aONyxZHGG5-gQhQnAMuF9dByLn0+treF8cRT06bqkA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jul 15, 2025 at 10:55 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Tue, Jul 15, 2025 at 10:37 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > I've attached updated patches that implement the idea we've discussed.
> > The patches still need to be polished but the implemented ideas seem
> > good. Feedback is very welcome.
> >
>
> Thank You for the patches. I just tried my hands on ptach001 yet, few concerns:
>
> 1)
> + else if (xlrec.wal_level == WAL_LEVEL_REPLICA &&
> + pg_atomic_read_u32(&ReplicationSlotCtl->n_inuse_logical_slots) == 0)
> + {
> + /*
> + * Disable the logical decoding if there is no in-use logical slot
> + * on the standby.
> + */
> + UpdateLogicalDecodingStatus(false);
> + }
>
> Due to above logic, the change in wal_level to replica on primary may
> end up disabling logical decoding on standby, even if logical decoding
> is still enabled on primary due to existence of slot.
>
> Steps:
> a) Create a slot on primary, but no slots on standby.
> b) Switch wal_level to logical on primary by doing a restart.
> c) Now switch wal_level back to replica on primary. This will end up
> disabling logical decoding on standby and slot creation will fail on
> standby as well.
>
> 2)
> In the same code, why don't we invalidate slots as we do when we
> receive XLOG_LOGICAL_DECODING_STATUS_CHANGE?

Good catch. I think decreasing wal_level to 'replica' should not
directly involve logical decoding status.

Related to this issue, I've considered the possibility of getting rid
of 'logical' from wal_level. Given the effective WAL level is
increased and decreased automatically upon the slot creation and
deletion, I think we would be able to get rid of 'logical' from
wal_level. One scenario where users would need to take additional
action is that users offload logical replication to the standby
server. In this case, the user would have to enable the logical
decoding on the primary server before creating a logical slot on the
standby. If such additional work is acceptable, we can remove it, and
I think it would be reasonable.

> 3)
> + EnsureLogicalDecodingEnabled();
>
> I do not understand the usage of above in synchronize_one_slot().
> Since 'EnsureLogicalDecodingEnabled' is a no-op for standby, it will
> do nothing here.

Right, will remove it.

>
> 4)
> - if (wal_level < WAL_LEVEL_LOGICAL)
> - ereport(ERROR,
> - errcode(ERRCODE_INVALID_PARAMETER_VALUE),
> - errmsg("replication slot synchronization requires \"wal_level\" >=
> \"logical\""));
> + if (!IsLogicalDecodingEnabled())
> + ereport(elevel,
> + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> +
>
> Is the change from 'ERROR' to 'elevel' intentional? With this change,
> slotsync worker will keep running even if logical decoding is not
> enabled on standby (or primary) yet.

Yes, this is because this function is called by the postmaster. But I
can see your point so I will deal with it in the next version patch. I
think the slotsync worker needs to exit when the logical decoding gets
disabled.

Regards,

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-17 18:55:54
Message-ID: CAD21AoBS=nOM1-EP0H-zVTvjF4BJLfbKTtFVb0NnjQ=Y-9u=WQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jul 17, 2025 at 2:36 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> the last slot on publisher and allow DROP to succeed when the
> subscription's drop_slot_force (a new subscription option) is set?
> Now, users can still be allowed to Drop the subscription, if it
> disassociates the subscription from the slot by using method explained
> in docs [1] (See Notes section). Similarly when a user is trying to
> drop the last logical slot via pg_drop_replication_slot, we will allow
> it only with the force option. This should ensure that the user is
> aware of the consequences of dropping the last slot.

I think even if we prevent the last logical replication that was used
for logical replication from being removed, the primary would continue
to accumulate WALs for that slot. I think it actually doesn't need to
hold WALs and dead catalog tuples in order to keep the effective WAL
level 'logical'. So probably it's better to 'reset' the slot, meaning
to clear the last slot's restart_lsn and catalog_xmin? Using such
option would work in interactive case but I'm not sure how works in
tools like shell scripts.

Regards,

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


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-18 03:28:04
Message-ID: CAA4eK1LHBGsnTHXZiOsP4QFWc-jdktvoycU5DWL-0ZX0UyuroA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jul 18, 2025 at 12:26 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Jul 17, 2025 at 2:36 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> > the last slot on publisher and allow DROP to succeed when the
> > subscription's drop_slot_force (a new subscription option) is set?
> > Now, users can still be allowed to Drop the subscription, if it
> > disassociates the subscription from the slot by using method explained
> > in docs [1] (See Notes section). Similarly when a user is trying to
> > drop the last logical slot via pg_drop_replication_slot, we will allow
> > it only with the force option. This should ensure that the user is
> > aware of the consequences of dropping the last slot.
>
> I think even if we prevent the last logical replication that was used
> for logical replication from being removed, the primary would continue
> to accumulate WALs for that slot. I think it actually doesn't need to
> hold WALs and dead catalog tuples in order to keep the effective WAL
> level 'logical'. So probably it's better to 'reset' the slot, meaning
> to clear the last slot's restart_lsn and catalog_xmin? Using such
> option would work in interactive case but I'm not sure how works in
> tools like shell scripts.
>

We can reset the slot's properties like catalog_xmin or restart_lsn at
the time of DROP SUBSCRIPTION even if it is the last logical slot on
publisher. We can probably use ALTER_REPLICATION_SLOT to do it. If we
want to do this, the steps during DROP SUBSCRIPTION would be to check
if the slot to be dropped is the last logical slot, if so, then we
will simply reset some of its elements, otherwise drop it. If we can't
drop it, then we can give a WARNING/NOTICE to the user. If a user has
set a new option like force_drop_slot then we will drop the slot
irrespective of whether it is a last slot or not. We can additionally
check wal_level on publisher as well before deciding whether to drop
the slot or not. If the wal_level is logical then we can probably drop
the slot.

--
With Regards,
Amit Kapila.


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-18 08:57:23
Message-ID: CAJpy0uCH=JGtF+fJo6gpmg+i6cZJmc77u3aMKFc+xxMTt82m-A@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jul 17, 2025 at 3:06 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Wed, Jun 18, 2025 at 3:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > >
> > > Thanks for the patch and sorry to be late in this conversation.
> > >
> > > The thing that worry me a bit with this is that that could be easy to attempt
> > > to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> > > by mistake on the primary. I think that this mistake is more likely to happen
> > > with a logical slot as compared to a physical slot.
> > >
> >
> > Yes, agreed. Another concern is the possibility of someone
> > intentionally using it and associating it with a subscription. If the
> > subscription is later dropped, it could also cause the slot to be
> > removed.
> >
>
> IIUC, your main concern here is that the last slot on
> primary/publisher could be dropped unintentionally by the user leading
> to invalidating the logical slots on any physical-standby connected
> with publisher, right?
>

Right.

> What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> the last slot on publisher and allow DROP to succeed when the
> subscription's drop_slot_force (a new subscription option) is set?
> Now, users can still be allowed to Drop the subscription, if it
> disassociates the subscription from the slot by using method explained
> in docs [1] (See Notes section). Similarly when a user is trying to
> drop the last logical slot via pg_drop_replication_slot, we will allow
> it only with the force option. This should ensure that the user is
> aware of the consequences of dropping the last slot.
>

One concern I have is regarding the default setting of
'force_slot_drop' . I assume the default value of this new DROP-SUB
argument will be 'false' to prevent customers from inadvertently
dropping the last slot on the publisher. But, would this be
acceptable, considering that users may have DROP-SUBSCRIPTION commands
in their scripts which would suddenly stop dropping slot now? OTOH, if
we keep the default as 'true', users might overlook changing it to
'false' when dropping the last subscription, and thus not solving any
purpose.

thanks
Shveta


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-18 09:33:01
Message-ID: CAA4eK1JQOYj98=3+6hTR8z9Og+ANPyN=XX40oFSwpq1-F9TJAw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jul 18, 2025 at 2:27 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Thu, Jul 17, 2025 at 3:06 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > On Wed, Jun 18, 2025 at 3:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > > >
> > > > Thanks for the patch and sorry to be late in this conversation.
> > > >
> > > > The thing that worry me a bit with this is that that could be easy to attempt
> > > > to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> > > > by mistake on the primary. I think that this mistake is more likely to happen
> > > > with a logical slot as compared to a physical slot.
> > > >
> > >
> > > Yes, agreed. Another concern is the possibility of someone
> > > intentionally using it and associating it with a subscription. If the
> > > subscription is later dropped, it could also cause the slot to be
> > > removed.
> > >
> >
> > IIUC, your main concern here is that the last slot on
> > primary/publisher could be dropped unintentionally by the user leading
> > to invalidating the logical slots on any physical-standby connected
> > with publisher, right?
> >
>
> Right.
>
> > What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> > the last slot on publisher and allow DROP to succeed when the
> > subscription's drop_slot_force (a new subscription option) is set?
> > Now, users can still be allowed to Drop the subscription, if it
> > disassociates the subscription from the slot by using method explained
> > in docs [1] (See Notes section). Similarly when a user is trying to
> > drop the last logical slot via pg_drop_replication_slot, we will allow
> > it only with the force option. This should ensure that the user is
> > aware of the consequences of dropping the last slot.
> >
>
> One concern I have is regarding the default setting of
> 'force_slot_drop' . I assume the default value of this new DROP-SUB
> argument will be 'false' to prevent customers from inadvertently
> dropping the last slot on the publisher. But, would this be
> acceptable, considering that users may have DROP-SUBSCRIPTION commands
> in their scripts which would suddenly stop dropping slot now?
>

That would only happen when users use this new idea of enabling
wal_level to 'logical' on the fly. I think the users having existing
setups with pub-sub would have kept the default wal_level to 'logical'
on publisher.

--
With Regards,
Amit Kapila.


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-21 05:18:16
Message-ID: CAJpy0uDqXum6SJ7si8q9B_bHAo9MZTzgja9R2Azkr4SV3cOOdA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jul 18, 2025 at 3:03 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Fri, Jul 18, 2025 at 2:27 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Thu, Jul 17, 2025 at 3:06 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > >
> > > On Wed, Jun 18, 2025 at 3:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> > > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > > > >
> > > > > Thanks for the patch and sorry to be late in this conversation.
> > > > >
> > > > > The thing that worry me a bit with this is that that could be easy to attempt
> > > > > to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> > > > > by mistake on the primary. I think that this mistake is more likely to happen
> > > > > with a logical slot as compared to a physical slot.
> > > > >
> > > >
> > > > Yes, agreed. Another concern is the possibility of someone
> > > > intentionally using it and associating it with a subscription. If the
> > > > subscription is later dropped, it could also cause the slot to be
> > > > removed.
> > > >
> > >
> > > IIUC, your main concern here is that the last slot on
> > > primary/publisher could be dropped unintentionally by the user leading
> > > to invalidating the logical slots on any physical-standby connected
> > > with publisher, right?
> > >
> >
> > Right.
> >
> > > What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> > > the last slot on publisher and allow DROP to succeed when the
> > > subscription's drop_slot_force (a new subscription option) is set?
> > > Now, users can still be allowed to Drop the subscription, if it
> > > disassociates the subscription from the slot by using method explained
> > > in docs [1] (See Notes section). Similarly when a user is trying to
> > > drop the last logical slot via pg_drop_replication_slot, we will allow
> > > it only with the force option. This should ensure that the user is
> > > aware of the consequences of dropping the last slot.
> > >
> >
> > One concern I have is regarding the default setting of
> > 'force_slot_drop' . I assume the default value of this new DROP-SUB
> > argument will be 'false' to prevent customers from inadvertently
> > dropping the last slot on the publisher. But, would this be
> > acceptable, considering that users may have DROP-SUBSCRIPTION commands
> > in their scripts which would suddenly stop dropping slot now?
> >
>
> That would only happen when users use this new idea of enabling
> wal_level to 'logical' on the fly. I think the users having existing
> setups with pub-sub would have kept the default wal_level to 'logical'
> on publisher.
>

Okay, but then we will have to avoid doing the enhancement of getting
rid of wal_level='logical' as suggested in [1].

Even if we do so, I am not very much convinced for this argument and its value.
--The value of ''force_slot_drop" will hold its meaning only in a
conditional scenario. Assuming default is false, then it will still
drop the slots until it is last slot and wal_level < logical on
primary. This behavior can seem a bit unintuitive or confusing from
the user's perspective.
--If the user is trying to actually retain the slot by giving
force_slot_drop=false , then how are we going to track that i.e.
distinguish from its default.

Bertrand has proposed a similar design in [2]. We can revisit that as well once.

I'm continuing to think it through and will share any further thoughts
if something comes to mind.

[1]: https://www.postgresql.org/message-id/CAD21AoD5aONyxZHGG5-gQhQnAMuF9dByLn0%2BtreF8cRT06bqkA%40mail.gmail.com
[2]: https://www.postgresql.org/message-id/aFPRqXR41xOhE597%40ip-10-97-1-34.eu-west-3.compute.internal

thanks
Shveta


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-21 05:54:18
Message-ID: CAJpy0uDsQ_1x81ZmaKksUqzFHyV4phuVpkpr=eNU291Z2nE-bg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 21, 2025 at 10:48 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Fri, Jul 18, 2025 at 3:03 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > On Fri, Jul 18, 2025 at 2:27 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Thu, Jul 17, 2025 at 3:06 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> > > >
> > > > On Wed, Jun 18, 2025 at 3:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > > > >
> > > > > On Wed, Jun 18, 2025 at 2:39 PM Bertrand Drouvot
> > > > > <bertranddrouvot(dot)pg(at)gmail(dot)com> wrote:
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > On Tue, Jun 10, 2025 at 02:00:55PM -0700, Masahiko Sawada wrote:
> > > > > > > > > > > > 0001 patch allows us to create a logical slot without WAL reservation.
> > > > > >
> > > > > > Thanks for the patch and sorry to be late in this conversation.
> > > > > >
> > > > > > The thing that worry me a bit with this is that that could be easy to attempt
> > > > > > to use the slot "by mistake" and then (as a consequence) trigger WAL reservation
> > > > > > by mistake on the primary. I think that this mistake is more likely to happen
> > > > > > with a logical slot as compared to a physical slot.
> > > > > >
> > > > >
> > > > > Yes, agreed. Another concern is the possibility of someone
> > > > > intentionally using it and associating it with a subscription. If the
> > > > > subscription is later dropped, it could also cause the slot to be
> > > > > removed.
> > > > >
> > > >
> > > > IIUC, your main concern here is that the last slot on
> > > > primary/publisher could be dropped unintentionally by the user leading
> > > > to invalidating the logical slots on any physical-standby connected
> > > > with publisher, right?
> > > >
> > >
> > > Right.
> > >
> > > > What if we make DROP SUBSCRIPTION fail if it can lead to removal of
> > > > the last slot on publisher and allow DROP to succeed when the
> > > > subscription's drop_slot_force (a new subscription option) is set?
> > > > Now, users can still be allowed to Drop the subscription, if it
> > > > disassociates the subscription from the slot by using method explained
> > > > in docs [1] (See Notes section). Similarly when a user is trying to
> > > > drop the last logical slot via pg_drop_replication_slot, we will allow
> > > > it only with the force option. This should ensure that the user is
> > > > aware of the consequences of dropping the last slot.
> > > >
> > >
> > > One concern I have is regarding the default setting of
> > > 'force_slot_drop' . I assume the default value of this new DROP-SUB
> > > argument will be 'false' to prevent customers from inadvertently
> > > dropping the last slot on the publisher. But, would this be
> > > acceptable, considering that users may have DROP-SUBSCRIPTION commands
> > > in their scripts which would suddenly stop dropping slot now?
> > >
> >
> > That would only happen when users use this new idea of enabling
> > wal_level to 'logical' on the fly. I think the users having existing
> > setups with pub-sub would have kept the default wal_level to 'logical'
> > on publisher.
> >
>
> Okay, but then we will have to avoid doing the enhancement of getting
> rid of wal_level='logical' as suggested in [1].
>
> Even if we do so, I am not very much convinced for this argument and its value.
> --The value of ''force_slot_drop" will hold its meaning only in a
> conditional scenario. Assuming default is false, then it will still
> drop the slots until it is last slot and wal_level < logical on
> primary. This behavior can seem a bit unintuitive or confusing from
> the user's perspective.
> --If the user is trying to actually retain the slot by giving
> force_slot_drop=false , then how are we going to track that i.e.
> distinguish from its default.
>
> Bertrand has proposed a similar design in [2]. We can revisit that as well once.
>
> I'm continuing to think it through and will share any further thoughts
> if something comes to mind.
>

How about a parameter named 'on_last_logical_slot' with possible
values: 'error', 'warn', 'drop', 'retain'?
Alternatively, we could use 'last_logical_slot_drop_policy' with
values: 'error', 'warn', 'allow'.

These parameters could be supported by both DROP SUBSCRIPTION and
pg_drop_replication_slot(), or alternatively implemented as a GUC on
the primary server. The default value should be either 'warn' or,
preferably, 'error' for safer behavior.

It seems more logical to me for this to be a GUC on the primary since
it falls within the primary’s scope.

With this, when the user attempts to drop a subscription associated
with the last slot on the primary, and the GUC is set to 'error', then
the DROP SUBSCRIPTION command should fail with a message like:

ERROR: cannot drop last logical slot; logical decoding would be
disabled on primary.
HINT: Disassociate subscription from the slot by executing ALTER
SUBSCRIPTION ... SET (slot_name = NONE)

And if the user tries to do pg_drop_replication_slot() on primary and
if it is the last logical slot, then error should be:

ERROR: cannot drop last logical slot; logical decoding would be disabled
HINT: Set last_logical_slot_drop_policy= 'allow' to override.

Thoughts?

thanks
Shveta


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-21 06:28:05
Message-ID: CAA4eK1KxJXFyOd378oSt=24S3LgkqUrawASEbGxoNsXR=wMxnw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 21, 2025 at 10:48 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Fri, Jul 18, 2025 at 3:03 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > >
> > > One concern I have is regarding the default setting of
> > > 'force_slot_drop' . I assume the default value of this new DROP-SUB
> > > argument will be 'false' to prevent customers from inadvertently
> > > dropping the last slot on the publisher. But, would this be
> > > acceptable, considering that users may have DROP-SUBSCRIPTION commands
> > > in their scripts which would suddenly stop dropping slot now?
> > >
> >
> > That would only happen when users use this new idea of enabling
> > wal_level to 'logical' on the fly. I think the users having existing
> > setups with pub-sub would have kept the default wal_level to 'logical'
> > on publisher.
> >
>
> Okay, but then we will have to avoid doing the enhancement of getting
> rid of wal_level='logical' as suggested in [1].
>
> Even if we do so, I am not very much convinced for this argument and its value.
> --The value of ''force_slot_drop" will hold its meaning only in a
> conditional scenario. Assuming default is false, then it will still
> drop the slots until it is last slot and wal_level < logical on
> primary. This behavior can seem a bit unintuitive or confusing from
> the user's perspective.
> --If the user is trying to actually retain the slot by giving
> force_slot_drop=false , then how are we going to track that i.e.
> distinguish from its default.
>
> Bertrand has proposed a similar design in [2]. We can revisit that as well once.
>

I am slightly hesitant to introduce multiple ways to enable logical
decoding/replication unless that is the only path as giving multiple
options to achieve the same thing can confuse users as to which one is
preferable and pros/cons of each.

--
With Regards,
Amit Kapila.


From: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-21 06:52:49
Message-ID: CAA4eK1J8Vq_G0hqUvqHdsn_jZydAmciPny+uQhYiie-zWsMzWg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 21, 2025 at 11:24 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Mon, Jul 21, 2025 at 10:48 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > I'm continuing to think it through and will share any further thoughts
> > if something comes to mind.
> >
>
> How about a parameter named 'on_last_logical_slot' with possible
> values: 'error', 'warn', 'drop', 'retain'?
> Alternatively, we could use 'last_logical_slot_drop_policy' with
> values: 'error', 'warn', 'allow'.
>
> These parameters could be supported by both DROP SUBSCRIPTION and
> pg_drop_replication_slot(), or alternatively implemented as a GUC on
> the primary server. The default value should be either 'warn' or,
> preferably, 'error' for safer behavior.
>
> It seems more logical to me for this to be a GUC on the primary since
> it falls within the primary’s scope.
>

This is worth considering. OTOH, it is possible that we are over
worried about users accidentally dropping the slot required for
continuing the logical decoding on the physical standby. In the
publisher-subscriber model, it seems quite intuitive that as soon as
the first subscription is created, we enable logical decoding on the
primary and when the last subscription is dropped, the logical
decoding on the publisher gets disabled. The case we are worrying
about is, for users, that enable logical decoding/replication on
physical standby based on the presence of a logical slot on the
primary. I think if we have documented clearly it is the
responsibility of users that they need to either (a) keep wal_level as
logical on primary, or (b) preserve a slot on the primary, it should
be sufficient. There could be multiple ways to preserve the slot, one
is users always create a special slot on the primary for this purpose
or we can provide a slot_option which users can specify/alter so that
they get ERROR/WARNING on the last such slot being dropped. I feel we
should choose the simplest option and rely on users to use the feature
appropriately. We can always enhance the feature in future versions
based on feedback from the field.

--
With Regards,
Amit Kapila.


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-21 07:35:30
Message-ID: CAJpy0uAYWhOiAEJSw5QRzrb3Dc2J0dGKiW+HSO8EV=+1nUHV8w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 21, 2025 at 12:23 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> I am slightly hesitant to introduce multiple ways to enable logical
> decoding/replication unless that is the only path as giving multiple
> options to achieve the same thing can confuse users as to which one is
> preferable and pros/cons of each.

Okay I understand your concern and it is a valid one.

> >
> > How about a parameter named 'on_last_logical_slot' with possible
> > values: 'error', 'warn', 'drop', 'retain'?
> > Alternatively, we could use 'last_logical_slot_drop_policy' with
> > values: 'error', 'warn', 'allow'.
> >
> > These parameters could be supported by both DROP SUBSCRIPTION and
> > pg_drop_replication_slot(), or alternatively implemented as a GUC on
> > the primary server. The default value should be either 'warn' or,
> > preferably, 'error' for safer behavior.
> >
> > It seems more logical to me for this to be a GUC on the primary since
> > it falls within the primary’s scope.
> >
>
> This is worth considering. OTOH, it is possible that we are over
> worried about users accidentally dropping the slot required for
> continuing the logical decoding on the physical standby. In the
> publisher-subscriber model, it seems quite intuitive that as soon as
> the first subscription is created, we enable logical decoding on the
> primary and when the last subscription is dropped, the logical
> decoding on the publisher gets disabled. The case we are worrying
> about is, for users, that enable logical decoding/replication on
> physical standby based on the presence of a logical slot on the
> primary. I think if we have documented clearly it is the
> responsibility of users that they need to either (a) keep wal_level as
> logical on primary, or (b) preserve a slot on the primary, it should
> be sufficient. There could be multiple ways to preserve the slot, one
> is users always create a special slot on the primary for this purpose
> or we can provide a slot_option which users can specify/alter so that
> they get ERROR/WARNING on the last such slot being dropped. I feel we
> should choose the simplest option and rely on users to use the feature
> appropriately. We can always enhance the feature in future versions
> based on feedback from the field.
>

I feel introducing a GUC is the simplest approach, as it provides
users with some control over the behavior when handling the last
logical slot. With this safeguard in place, we can be more confident
about eventually removing wal_level = logical, either now or in the
future.

That said, if we decide it's acceptable to proceed without this
additional ERROR/WARNING mechanism, I'm fine with that as well. But it
does leave users with a small risk of unintentionally disabling
logical decoding, even with proper documentation. Let's see what
others think here.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-21 23:33:13
Message-ID: CAD21AoCK1+etYGygYuJmw+cXWXpQMCXKZW80SYSz2b+XbEO4sw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sun, Jul 20, 2025 at 11:53 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Mon, Jul 21, 2025 at 11:24 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Mon, Jul 21, 2025 at 10:48 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > I'm continuing to think it through and will share any further thoughts
> > > if something comes to mind.
> > >
> >
> > How about a parameter named 'on_last_logical_slot' with possible
> > values: 'error', 'warn', 'drop', 'retain'?
> > Alternatively, we could use 'last_logical_slot_drop_policy' with
> > values: 'error', 'warn', 'allow'.
> >
> > These parameters could be supported by both DROP SUBSCRIPTION and
> > pg_drop_replication_slot(), or alternatively implemented as a GUC on
> > the primary server. The default value should be either 'warn' or,
> > preferably, 'error' for safer behavior.
> >
> > It seems more logical to me for this to be a GUC on the primary since
> > it falls within the primary’s scope.
> >
>
> This is worth considering. OTOH, it is possible that we are over
> worried about users accidentally dropping the slot required for
> continuing the logical decoding on the physical standby. In the
> publisher-subscriber model, it seems quite intuitive that as soon as
> the first subscription is created, we enable logical decoding on the
> primary and when the last subscription is dropped, the logical
> decoding on the publisher gets disabled. The case we are worrying
> about is, for users, that enable logical decoding/replication on
> physical standby based on the presence of a logical slot on the
> primary. I think if we have documented clearly it is the
> responsibility of users that they need to either (a) keep wal_level as
> logical on primary, or (b) preserve a slot on the primary, it should
> be sufficient. There could be multiple ways to preserve the slot, one
> is users always create a special slot on the primary for this purpose
> or we can provide a slot_option which users can specify/alter so that
> they get ERROR/WARNING on the last such slot being dropped. I feel we
> should choose the simplest option and rely on users to use the feature
> appropriately. We can always enhance the feature in future versions
> based on feedback from the field.

Yes, I agree. The main patch focuses on the part where we
automatically change the effective WAL level upon the logical slot
creation and deletion (and potentially remove 'logical' from
wal_level), and other things are implemented as additional features in
a separate patch. In the case where users are using logical decoding
only on the standbys, we might want to have a concept like empty
logical slots as we have discussed because users would not want to let
a logical slot on the primary preserve anything. But it's a separate
discussion whether we provide a way to protect such a slot from being
dropped or used mistakenly.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-23 06:44:37
Message-ID: CAJpy0uDb2aUsJ-s0vmwd-GR_j=Z8VG+fxT_yi15KNXjWkDdg-Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jul 22, 2025 at 5:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Yes, I agree. The main patch focuses on the part where we
> automatically change the effective WAL level upon the logical slot
> creation and deletion (and potentially remove 'logical' from
> wal_level), and other things are implemented as additional features in
> a separate patch.

I am keeping my focus on patch001 until we decide further on how to
protect the slot. Apart from few comments in [1], please find one
more concern:

There is a race condition between creating and dropping a replication
slot when enabling or disabling logical decoding. We might end up with
logical decoding disabled even when a logical slot is present.

Steps:
1) Set wal_level=replica on primary.
2) Create logical_slot1 which will enable logical decoding, causing
effective_wal_level to become logical.
3) Drop logical_slot1 and pause execution inside
DisableLogicalDecodingIfNecessary() right after the
'n_inuse_logical_slots' check using a debugger.
4) In another session, create logical_slot2. It will attempt to enable
logical-decoding but since it is already enabled,
EnsureLogicalDecodingEnabled() will be a no-op.
5) Release debugger of drop-slot, it will disable logical decoding.

Ultimately, logical_slot2is present while logical decoding is disabled
and thus we see this:

postgres=# select slot_name from pg_replication_slots;
slot_name
---------------
logical_slot2

postgres=# show effective_wal_level;
effective_wal_level
---------------------
replica
(1 row)

postgres=# select pg_logical_slot_get_changes('logical_slot2', NULL,
NULL, 'proto_version', '4', 'publication_names', 'pub');
ERROR: logical decoding is not enabled
HINT: Set "wal_level" >= "logical" or create at least one logical slot.

Shall we acquire LogicalDecodingControlLock in exclusive mode at a
little earlier stage? Currently we acquire it after
IsLogicalDecodingEnabled() check. I think we shall acquire it before
this check in in both enable and disable flow?

[1]: https://www.postgresql.org/message-id/CAJpy0uC0e%3DJ7L4q9RnQ3pbSAtvWy40r9qp3tr41zoogHQmDO8g%40mail.gmail.com

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-25 06:14:53
Message-ID: CAD21AoD6SRkF+pLEwDEiTwSFJuHA+xTh+59SSscEsrAgSL4ysQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jul 22, 2025 at 11:44 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Tue, Jul 22, 2025 at 5:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > Yes, I agree. The main patch focuses on the part where we
> > automatically change the effective WAL level upon the logical slot
> > creation and deletion (and potentially remove 'logical' from
> > wal_level), and other things are implemented as additional features in
> > a separate patch.
>
> I am keeping my focus on patch001 until we decide further on how to
> protect the slot.

Yeah, I also dropped the additional feature patch from the patch set for now.

> Apart from few comments in [1], please find one
> more concern:
>
> There is a race condition between creating and dropping a replication
> slot when enabling or disabling logical decoding. We might end up with
> logical decoding disabled even when a logical slot is present.
>
> Steps:
> 1) Set wal_level=replica on primary.
> 2) Create logical_slot1 which will enable logical decoding, causing
> effective_wal_level to become logical.
> 3) Drop logical_slot1 and pause execution inside
> DisableLogicalDecodingIfNecessary() right after the
> 'n_inuse_logical_slots' check using a debugger.
> 4) In another session, create logical_slot2. It will attempt to enable
> logical-decoding but since it is already enabled,
> EnsureLogicalDecodingEnabled() will be a no-op.
> 5) Release debugger of drop-slot, it will disable logical decoding.
>
> Ultimately, logical_slot2is present while logical decoding is disabled
> and thus we see this:
>
> postgres=# select slot_name from pg_replication_slots;
> slot_name
> ---------------
> logical_slot2
>
> postgres=# show effective_wal_level;
> effective_wal_level
> ---------------------
> replica
> (1 row)
>
> postgres=# select pg_logical_slot_get_changes('logical_slot2', NULL,
> NULL, 'proto_version', '4', 'publication_names', 'pub');
> ERROR: logical decoding is not enabled
> HINT: Set "wal_level" >= "logical" or create at least one logical slot.
>
> Shall we acquire LogicalDecodingControlLock in exclusive mode at a
> little earlier stage? Currently we acquire it after
> IsLogicalDecodingEnabled() check. I think we shall acquire it before
> this check in in both enable and disable flow?

Thank you for testing the patch!

I've reworked the locking part in the patch. The attached v4 patch
should address all review comments including your previous
comments[1].

Regards,

[1] https://www.postgresql.org/message-id/CAJpy0uC0e%3DJ7L4q9RnQ3pbSAtvWy40r9qp3tr41zoogHQmDO8g%40mail.gmail.com

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

Attachment Content-Type Size
v4-0001-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 48.6 KB
v4-0002-Add-regression-tests-for-online-logical-decoding-.patch application/octet-stream 8.8 KB

From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: 'Masahiko Sawada' <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: RE: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-28 12:34:21
Message-ID: OSCPR01MB149663D242F6E97630758DD6EF55AA@OSCPR01MB14966.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Dear Sawada-san,

> Thank you for testing the patch!
>
> I've reworked the locking part in the patch. The attached v4 patch
> should address all review comments including your previous
> comments[1].

Thanks for making the patch! I resumed to spending time for the project.
Here are my comments.

1.
Just in case - can you modify xlogdesc.c based on your fix?

2.
Currently pg_upgrade has below checking:
```
if (nslots_on_old > 0 && strcmp(wal_level, "logical") != 0)
pg_fatal("\"wal_level\" must be \"logical\" but is set to \"%s\"",
wal_level);
```

But this can be relaxed because wal_level can be adjusted appropriately. IIUC it
is enough to be higher than "minimal". Is it right?

3.
Currently pg_createsubscriber has below checking:
```
if (strcmp(wal_level, "logical") != 0)
{
pg_log_error("publisher requires \"wal_level\" >= \"logical\"");
failed = true;
}
```

I feel the checking is completely not needed, because pg_createsubscriber needs
a streaming standby and wal_level = minimal cannot be set with this node placement.
Thought?

4.
We should update PG_CONTROL_VERSION and pg_controldata as well.

5.
I'm wondering how pg_resetwal handles. Since all the replication slot cannot be
used after the command, logicalDecodingEnabled can be set to false, right?

Best regards,
Hayato Kuroda
FUJITSU LIMITED


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-28 21:11:39
Message-ID: CAD21AoDLO2GVeHB5i0dZjDO0t3sdoswNxB7KS=a60FAZHPiR1A@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 28, 2025 at 5:34 AM Hayato Kuroda (Fujitsu)
<kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
>
> Dear Sawada-san,
>
> > Thank you for testing the patch!
> >
> > I've reworked the locking part in the patch. The attached v4 patch
> > should address all review comments including your previous
> > comments[1].
>
> Thanks for making the patch! I resumed to spending time for the project.

Thank you for reviewing the patch!

> Here are my comments.
>
> 1.
> Just in case - can you modify xlogdesc.c based on your fix?

Will fix.

>
> 2.
> Currently pg_upgrade has below checking:
> ```
> if (nslots_on_old > 0 && strcmp(wal_level, "logical") != 0)
> pg_fatal("\"wal_level\" must be \"logical\" but is set to \"%s\"",
> wal_level);
> ```
>
> But this can be relaxed because wal_level can be adjusted appropriately. IIUC it
> is enough to be higher than "minimal". Is it right?

Right, will fix.

>
> 3.
> Currently pg_createsubscriber has below checking:
> ```
> if (strcmp(wal_level, "logical") != 0)
> {
> pg_log_error("publisher requires \"wal_level\" >= \"logical\"");
> failed = true;
> }
> ```
>
> I feel the checking is completely not needed, because pg_createsubscriber needs
> a streaming standby and wal_level = minimal cannot be set with this node placement.
> Thought?

Yes, we can get rid of this check.

>
> 4.
> We should update PG_CONTROL_VERSION and pg_controldata as well.

Right, I'll update pg_controldata. For PG_CONTROL_VERSION, I'm going
to update before the push.

>
> 5.
> I'm wondering how pg_resetwal handles. Since all the replication slot cannot be
> used after the command, logicalDecodingEnabled can be set to false, right?

I think that logical decoding remains enabled as long as logical slots
are present. For example, it remains enabled even if the sole logical
slot is invalidated.

Regards,

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


From: vignesh C <vignesh21(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-29 04:44:23
Message-ID: CALDaNm3BfG1hpWVEaqwBgXpcEGSQXDi536OzB2=8SFTz-v+3CA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, 25 Jul 2025 at 11:45, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Tue, Jul 22, 2025 at 11:44 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Tue, Jul 22, 2025 at 5:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > Yes, I agree. The main patch focuses on the part where we
> > > automatically change the effective WAL level upon the logical slot
> > > creation and deletion (and potentially remove 'logical' from
> > > wal_level), and other things are implemented as additional features in
> > > a separate patch.
> >
> > I am keeping my focus on patch001 until we decide further on how to
> > protect the slot.
>
> Yeah, I also dropped the additional feature patch from the patch set for now.
>
> > Apart from few comments in [1], please find one
> > more concern:
> >
> > There is a race condition between creating and dropping a replication
> > slot when enabling or disabling logical decoding. We might end up with
> > logical decoding disabled even when a logical slot is present.
> >
> > Steps:
> > 1) Set wal_level=replica on primary.
> > 2) Create logical_slot1 which will enable logical decoding, causing
> > effective_wal_level to become logical.
> > 3) Drop logical_slot1 and pause execution inside
> > DisableLogicalDecodingIfNecessary() right after the
> > 'n_inuse_logical_slots' check using a debugger.
> > 4) In another session, create logical_slot2. It will attempt to enable
> > logical-decoding but since it is already enabled,
> > EnsureLogicalDecodingEnabled() will be a no-op.
> > 5) Release debugger of drop-slot, it will disable logical decoding.
> >
> > Ultimately, logical_slot2is present while logical decoding is disabled
> > and thus we see this:
> >
> > postgres=# select slot_name from pg_replication_slots;
> > slot_name
> > ---------------
> > logical_slot2
> >
> > postgres=# show effective_wal_level;
> > effective_wal_level
> > ---------------------
> > replica
> > (1 row)
> >
> > postgres=# select pg_logical_slot_get_changes('logical_slot2', NULL,
> > NULL, 'proto_version', '4', 'publication_names', 'pub');
> > ERROR: logical decoding is not enabled
> > HINT: Set "wal_level" >= "logical" or create at least one logical slot.
> >
> > Shall we acquire LogicalDecodingControlLock in exclusive mode at a
> > little earlier stage? Currently we acquire it after
> > IsLogicalDecodingEnabled() check. I think we shall acquire it before
> > this check in in both enable and disable flow?
>
> Thank you for testing the patch!
>
> I've reworked the locking part in the patch. The attached v4 patch
> should address all review comments including your previous
> comments[1].

Few comments:
1) pg_waldump not handled for the new WAL record added
XLOG_LOGICAL_DECODING_STATUS_CHANGE:
+ XLogRegisterData(&logical_decoding, sizeof(bool));
+ recptr = XLogInsert(RM_XLOG_ID,
XLOG_LOGICAL_DECODING_STATUS_CHANGE);
+ XLogFlush(recptr);

rmgr: XLOG len (rec/tot): 54/ 54, tx: 0, lsn:
0/017633D8, prev 0/01763360, desc: PARAMETER_CHANGE
max_connections=100 max_worker_processes=8 max_wal_senders=10
max_prepared_xacts=10 max_locks_per_xact=64 wal_level=replica
wal_log_hints=off track_commit_timestamp=off
rmgr: XLOG len (rec/tot): 27/ 27, tx: 0, lsn:
0/01763410, prev 0/017633D8, desc: UNKNOWN (f0)
rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn:
0/01763430, prev 0/01763410, desc: RUNNING_XACTS nextXid 754
latestCompletedXid 753 oldestRunningXid 754

2) Similarly pg_walinspect also should be handled for the new WAL record added:
postgres=# SELECT * FROM pg_get_wal_records_info('0/017633D8', '0/01763468');
start_lsn | end_lsn | prev_lsn | xid | resource_manager |
record_type | record_length | main_data_length | fpi_length |
description
| block_ref
------------+------------+------------+-----+------------------+------------------+---------------+------------------+------------+-----------------------------------------------------------
---------------------------------------------------------------------------------------------------------------+-----------
0/017633D8 | 0/01763410 | 0/01763360 | 0 | XLOG |
PARAMETER_CHANGE | 54 | 28 | 0 |
max_connections=100 max_worker_processes=8 max_wal_senders
=10 max_prepared_xacts=10 max_locks_per_xact=64 wal_level=replica
wal_log_hints=off track_commit_timestamp=off |
0/01763410 | 0/01763430 | 0/017633D8 | 0 | XLOG |
UNKNOWN (f0) | 27 | 1 | 0 |

|
0/01763430 | 0/01763468 | 0/01763410 | 0 | Standby |
RUNNING_XACTS | 50 | 24 | 0 |
nextXid 754 latestCompletedXid 753 oldestRunningXid 754

|
(3 rows)

3) Should this be the other way around? Would it be better to throw
the error earlier, instead of waiting for the running transactions to
finish?
@@ -136,6 +137,9 @@ create_logical_replication_slot(char *name, char *plugin,
temporary ?
RS_TEMPORARY : RS_EPHEMERAL, two_phase,
failover, false);

+ EnsureLogicalDecodingEnabled();
+ CheckLogicalDecodingRequirements();

4) The includes xlog_internal, xlogutils, atomics, lwlock, procsignal,
shmem, standby and guc is not required, I was able to compile without
it:
+ * src/backend/replication/logical/logicalctl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/xlog_internal.h"
+#include "access/xlogutils.h"
+#include "access/xloginsert.h"
+#include "catalog/pg_control.h"
+#include "port/atomics.h"
+#include "miscadmin.h"
+#include "storage/lwlock.h"
+#include "storage/procarray.h"
+#include "storage/procsignal.h"
+#include "storage/ipc.h"
+#include "storage/lmgr.h"
+#include "storage/shmem.h"
+#include "storage/standby.h"
+#include "replication/logicalctl.h"
+#include "replication/slot.h"
+#include "utils/guc.h"
+#include "utils/wait_event_types.h"

5) I felt this change is not related to this patch:
@@ -1144,7 +1152,7 @@ slotsync_reread_config(void)
if (old_sync_replication_slots != sync_replication_slots)
{
ereport(LOG,
- /* translator: %s is a GUC variable name */
+ /* translator: %s is a GUC variable name */
errmsg("replication slot
synchronization worker will shut down because \"%s\" is disabled",
"sync_replication_slots"));
proc_exit(0);

6) Can we include the high level design in the commit message and also
the other possible designs that were considered before finalizing on
this, it will help new reviewers to get a head start as the thread is
a long thread.

7) I did not see documentation added, can we add the required
documentation for this.

8) The new test file added should be included in meson.build file

Regards,
Vignesh


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-29 05:02:35
Message-ID: CAJpy0uDxap0YKLx5N45_Vz49QARjioUaOb1qpaiV0PBkYoivRg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Jul 25, 2025 at 11:45 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> Thank you for testing the patch!
>
> I've reworked the locking part in the patch. The attached v4 patch
> should address all review comments including your previous
> comments[1].
>

Thank You for the patch. I have not reviewed fully, but please find
few comments:

1)
CreateReplicationSlot():

Assert(cmd->kind == REPLICATION_KIND_LOGICAL);
+ EnsureLogicalDecodingEnabled();
CheckLogicalDecodingRequirements();
ReplicationSlotCreate(...);

We may have another race-condition here. We have
EnsureLogicalDecodingEnabled() before ReplicationSlotCreate(). It
means we are enabling logical-decoding before incrementing
LogicalDecodingCtl->n_logical_slots. So before we increment
LogicalDecodingCtl->n_logical_slots through ReplicationSlotCreate(),
another session may try to meanwhile drop the logical slot (another
one and last one), and thus it may end up disabling logical-decoding
as it will find n_logical_slots as 0.

Steps:
a) Create logical slot logical_slot1 on primary.
b) Create publication pub1.
c) During Create-sub on subscriber, stop walsender after
EnsureLogicalDecodingEnabled() by attaching debugger.
d) Drop logical_slot1 on primary.
e) Release the walsender debugger.

2)
create_logical_replication_slot:

ReplicationSlotCreate(name, true
....
+ EnsureLogicalDecodingEnabled();
+ CheckLogicalDecodingRequirements();

Earlier we had CheckLogicalDecodingRequirements() before we actually
created the slot. Now we had it after slot-creation. It makes sense to
do Logical-Decoding related checks post EnsureLogicalDecodingEnabled,
but 'CheckSlotRequirements' should be done prior to slot-creation.
Otherwise we will end up creating the slot and later dropping it when
it should not have been created in the first place (for say wal_level
< replica).

3)
+ EnsureLogicalDecodingEnabled();
+

We can get rid of this from slotsync as this is no-op on standby

4)
pg_sync_replication_slots()
if (!RecoveryInProgress())
ereport(ERROR,

errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("replication slots can only be
synchronized to a standby server"));

+ EnsureLogicalDecodingEnabled();

This API is called on standby alone, so EnsureLogicalDecodingEnabled
is not needed here either.

thanks
Shveta


From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: 'Masahiko Sawada' <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: RE: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-30 07:22:36
Message-ID: OSCPR01MB14966C5E31CA0ACAD07AF8B5FF524A@OSCPR01MB14966.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Dear Sawada-san,

While reading more, I found a race condition. In this case the effective_wal_level
can be logical even when there is no logical slot.
UpdateLogicalDecodingStatusEndOfRecovery() checks the number of slots of the logical
slot then release the lock once. Then startup process acquires the lock once and
compare with IsLogicalDecodingEnabled(), then update the status afterward if needed.
So, wal_level can be inconsistent if the status is changed after the n_logical_slots
is read.

Steps:
a) constructed a primary-standby system
b) createad a logical slot on the primary
c) createad a logical slot on the standby
d) sent a promote signal to standby
e) dropped a logical slot on standby, just after startup process released
LogicalDecodingControlLock in UpdateLogicalDecodingStatusEndOfRecovery().

After the above, effective_wal_level was keep turning on. Is it the expected behavior?
```
postgres=# SELECT slot_name FROM pg_replication_slots ;
slot_name
-----------
(0 rows)

postgres=# show effective_wal_level ;
effective_wal_level
---------------------
logical
(1 row)

postgres=# SELECT pg_is_in_recovery ();
pg_is_in_recovery
-------------------
f
(1 row)
```

Best regards,
Hayato Kuroda
FUJITSU LIMITED


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-30 17:54:14
Message-ID: CAD21AoDFkWxeG6bX1EkGY9=i6P0Xz-PCrw41XNFFGfJXaft4eA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Jul 30, 2025 at 12:22 AM Hayato Kuroda (Fujitsu)
<kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
>
> Dear Sawada-san,
>
> While reading more, I found a race condition.

Thank you for reviewing the patch!

> In this case the effective_wal_level
> can be logical even when there is no logical slot.
> UpdateLogicalDecodingStatusEndOfRecovery() checks the number of slots of the logical
> slot then release the lock once. Then startup process acquires the lock once and
> compare with IsLogicalDecodingEnabled(), then update the status afterward if needed.
> So, wal_level can be inconsistent if the status is changed after the n_logical_slots
> is read.
>
> Steps:
> a) constructed a primary-standby system
> b) createad a logical slot on the primary
> c) createad a logical slot on the standby
> d) sent a promote signal to standby
> e) dropped a logical slot on standby, just after startup process released
> LogicalDecodingControlLock in UpdateLogicalDecodingStatusEndOfRecovery().
>
> After the above, effective_wal_level was keep turning on. Is it the expected behavior?

No, we need to fix it.

I thought we could fix this issue by checking the number of in-use
logical slots while holding ReplicationSlotControlLock and
LogicalDecodingControlLock, but it seems we need to deal with another
race condition too between backends and startup processes at the end
of recovery.

Currently the backend skips controlling logical decoding status if the
server is in recovery (by checking RecoveryInProgress()), but it's
possible that a backend process tries to drop a logical slot after the
startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
before accepting writes. In this case, the backend ends up not
disabling logical decoding and it remains enabled. I think we would
somehow need to delay the logical decoding status change in this
period until the recovery completes.

Regards,

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


From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: 'Masahiko Sawada' <sawada(dot)mshk(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: RE: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-07-31 12:00:16
Message-ID: OSCPR01MB1496686BCD0C40745BB03BBB3F527A@OSCPR01MB14966.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Dear Sawada-san,

> I thought we could fix this issue by checking the number of in-use
> logical slots while holding ReplicationSlotControlLock and
> LogicalDecodingControlLock, but it seems we need to deal with another
> race condition too between backends and startup processes at the end
> of recovery.
>
> Currently the backend skips controlling logical decoding status if the
> server is in recovery (by checking RecoveryInProgress()), but it's
> possible that a backend process tries to drop a logical slot after the
> startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
> before accepting writes.

Right. I also verified on local and found that
ReplicationSlotDropAcquired()->DisableLogicalDecodingIfNecessary() sometimes
skips to modify the status because RecoveryInProgress is still false.

> In this case, the backend ends up not
> disabling logical decoding and it remains enabled. I think we would
> somehow need to delay the logical decoding status change in this
> period until the recovery completes.

My primitive idea was to 1) keep startup acquiring the lock till end of recovery
and 2) DisableLogicalDecodingIfNecessary() acquires lock before checking the
recovery status, but it could not work well. Not sure but WaitForProcSignalBarrier()
stucked if the process acquired LogicalDecodingControlLock lock....

Best regards,
Hayato Kuroda
FUJITSU LIMITED


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-01 23:23:16
Message-ID: CAD21AoB=Rf-SASOJR2WqvWcrA5Q3S2oUBACVLdJPaA8x6EchBA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Jul 31, 2025 at 5:00 AM Hayato Kuroda (Fujitsu)
<kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
>
> Dear Sawada-san,
>
> > I thought we could fix this issue by checking the number of in-use
> > logical slots while holding ReplicationSlotControlLock and
> > LogicalDecodingControlLock, but it seems we need to deal with another
> > race condition too between backends and startup processes at the end
> > of recovery.
> >
> > Currently the backend skips controlling logical decoding status if the
> > server is in recovery (by checking RecoveryInProgress()), but it's
> > possible that a backend process tries to drop a logical slot after the
> > startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
> > before accepting writes.
>
> Right. I also verified on local and found that
> ReplicationSlotDropAcquired()->DisableLogicalDecodingIfNecessary() sometimes
> skips to modify the status because RecoveryInProgress is still false.
>
> > In this case, the backend ends up not
> > disabling logical decoding and it remains enabled. I think we would
> > somehow need to delay the logical decoding status change in this
> > period until the recovery completes.
>
> My primitive idea was to 1) keep startup acquiring the lock till end of recovery
> and 2) DisableLogicalDecodingIfNecessary() acquires lock before checking the
> recovery status, but it could not work well. Not sure but WaitForProcSignalBarrier()
> stucked if the process acquired LogicalDecodingControlLock lock....

I think that it's not realistic to keep holding a lwlock until the
recovery actually completes because we perform a checkpoint after
that.

In the latest version patch I attached, I introduce a flag on shared
memory to delay any logical decoding status change until the recovery
completes. The implementation got more complex than I expected but I
don't have a better idea. I'm open to other approaches. Also, I
incorporated all comments I got so far[1][2][3] and updated the
documentation.

Regards,

[1] https://www.postgresql.org/message-id/CALDaNm3BfG1hpWVEaqwBgXpcEGSQXDi536OzB2%3D8SFTz-v%2B3CA%40mail.gmail.com
[2] https://www.postgresql.org/message-id/CAJpy0uDxap0YKLx5N45_Vz49QARjioUaOb1qpaiV0PBkYoivRg%40mail.gmail.com
[3] https://www.postgresql.org/message-id/OSCPR01MB149663D242F6E97630758DD6EF55AA%40OSCPR01MB14966.jpnprd01.prod.outlook.com

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

Attachment Content-Type Size
v5-0001-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 85.7 KB

From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: vignesh C <vignesh21(at)gmail(dot)com>
Cc: shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-01 23:24:51
Message-ID: CAD21AoBObzgdOgZOXPb0zGWcNXdkXABj_1u+9TFZyQBt4aY=pw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 28, 2025 at 9:44 PM vignesh C <vignesh21(at)gmail(dot)com> wrote:
>
> On Fri, 25 Jul 2025 at 11:45, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Tue, Jul 22, 2025 at 11:44 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Tue, Jul 22, 2025 at 5:03 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > Yes, I agree. The main patch focuses on the part where we
> > > > automatically change the effective WAL level upon the logical slot
> > > > creation and deletion (and potentially remove 'logical' from
> > > > wal_level), and other things are implemented as additional features in
> > > > a separate patch.
> > >
> > > I am keeping my focus on patch001 until we decide further on how to
> > > protect the slot.
> >
> > Yeah, I also dropped the additional feature patch from the patch set for now.
> >
> > > Apart from few comments in [1], please find one
> > > more concern:
> > >
> > > There is a race condition between creating and dropping a replication
> > > slot when enabling or disabling logical decoding. We might end up with
> > > logical decoding disabled even when a logical slot is present.
> > >
> > > Steps:
> > > 1) Set wal_level=replica on primary.
> > > 2) Create logical_slot1 which will enable logical decoding, causing
> > > effective_wal_level to become logical.
> > > 3) Drop logical_slot1 and pause execution inside
> > > DisableLogicalDecodingIfNecessary() right after the
> > > 'n_inuse_logical_slots' check using a debugger.
> > > 4) In another session, create logical_slot2. It will attempt to enable
> > > logical-decoding but since it is already enabled,
> > > EnsureLogicalDecodingEnabled() will be a no-op.
> > > 5) Release debugger of drop-slot, it will disable logical decoding.
> > >
> > > Ultimately, logical_slot2is present while logical decoding is disabled
> > > and thus we see this:
> > >
> > > postgres=# select slot_name from pg_replication_slots;
> > > slot_name
> > > ---------------
> > > logical_slot2
> > >
> > > postgres=# show effective_wal_level;
> > > effective_wal_level
> > > ---------------------
> > > replica
> > > (1 row)
> > >
> > > postgres=# select pg_logical_slot_get_changes('logical_slot2', NULL,
> > > NULL, 'proto_version', '4', 'publication_names', 'pub');
> > > ERROR: logical decoding is not enabled
> > > HINT: Set "wal_level" >= "logical" or create at least one logical slot.
> > >
> > > Shall we acquire LogicalDecodingControlLock in exclusive mode at a
> > > little earlier stage? Currently we acquire it after
> > > IsLogicalDecodingEnabled() check. I think we shall acquire it before
> > > this check in in both enable and disable flow?
> >
> > Thank you for testing the patch!
> >
> > I've reworked the locking part in the patch. The attached v4 patch
> > should address all review comments including your previous
> > comments[1].
>
> Few comments:
> 1) pg_waldump not handled for the new WAL record added
> XLOG_LOGICAL_DECODING_STATUS_CHANGE:
> + XLogRegisterData(&logical_decoding, sizeof(bool));
> + recptr = XLogInsert(RM_XLOG_ID,
> XLOG_LOGICAL_DECODING_STATUS_CHANGE);
> + XLogFlush(recptr);
>
> rmgr: XLOG len (rec/tot): 54/ 54, tx: 0, lsn:
> 0/017633D8, prev 0/01763360, desc: PARAMETER_CHANGE
> max_connections=100 max_worker_processes=8 max_wal_senders=10
> max_prepared_xacts=10 max_locks_per_xact=64 wal_level=replica
> wal_log_hints=off track_commit_timestamp=off
> rmgr: XLOG len (rec/tot): 27/ 27, tx: 0, lsn:
> 0/01763410, prev 0/017633D8, desc: UNKNOWN (f0)
> rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn:
> 0/01763430, prev 0/01763410, desc: RUNNING_XACTS nextXid 754
> latestCompletedXid 753 oldestRunningXid 754
>
> 2) Similarly pg_walinspect also should be handled for the new WAL record added:
> postgres=# SELECT * FROM pg_get_wal_records_info('0/017633D8', '0/01763468');
> start_lsn | end_lsn | prev_lsn | xid | resource_manager |
> record_type | record_length | main_data_length | fpi_length |
> description
> | block_ref
> ------------+------------+------------+-----+------------------+------------------+---------------+------------------+------------+-----------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------+-----------
> 0/017633D8 | 0/01763410 | 0/01763360 | 0 | XLOG |
> PARAMETER_CHANGE | 54 | 28 | 0 |
> max_connections=100 max_worker_processes=8 max_wal_senders
> =10 max_prepared_xacts=10 max_locks_per_xact=64 wal_level=replica
> wal_log_hints=off track_commit_timestamp=off |
> 0/01763410 | 0/01763430 | 0/017633D8 | 0 | XLOG |
> UNKNOWN (f0) | 27 | 1 | 0 |
>
> |
> 0/01763430 | 0/01763468 | 0/01763410 | 0 | Standby |
> RUNNING_XACTS | 50 | 24 | 0 |
> nextXid 754 latestCompletedXid 753 oldestRunningXid 754
>
> |
> (3 rows)
>
> 3) Should this be the other way around? Would it be better to throw
> the error earlier, instead of waiting for the running transactions to
> finish?
> @@ -136,6 +137,9 @@ create_logical_replication_slot(char *name, char *plugin,
> temporary ?
> RS_TEMPORARY : RS_EPHEMERAL, two_phase,
> failover, false);
>
> + EnsureLogicalDecodingEnabled();
> + CheckLogicalDecodingRequirements();
>
> 4) The includes xlog_internal, xlogutils, atomics, lwlock, procsignal,
> shmem, standby and guc is not required, I was able to compile without
> it:
> + * src/backend/replication/logical/logicalctl.c
> + *
> + *-------------------------------------------------------------------------
> + */
> +#include "postgres.h"
> +
> +#include "access/xlog_internal.h"
> +#include "access/xlogutils.h"
> +#include "access/xloginsert.h"
> +#include "catalog/pg_control.h"
> +#include "port/atomics.h"
> +#include "miscadmin.h"
> +#include "storage/lwlock.h"
> +#include "storage/procarray.h"
> +#include "storage/procsignal.h"
> +#include "storage/ipc.h"
> +#include "storage/lmgr.h"
> +#include "storage/shmem.h"
> +#include "storage/standby.h"
> +#include "replication/logicalctl.h"
> +#include "replication/slot.h"
> +#include "utils/guc.h"
> +#include "utils/wait_event_types.h"
>
> 5) I felt this change is not related to this patch:
> @@ -1144,7 +1152,7 @@ slotsync_reread_config(void)
> if (old_sync_replication_slots != sync_replication_slots)
> {
> ereport(LOG,
> - /* translator: %s is a GUC variable name */
> + /* translator: %s is a GUC variable name */
> errmsg("replication slot
> synchronization worker will shut down because \"%s\" is disabled",
> "sync_replication_slots"));
> proc_exit(0);
>
> 6) Can we include the high level design in the commit message and also
> the other possible designs that were considered before finalizing on
> this, it will help new reviewers to get a head start as the thread is
> a long thread.
>
> 7) I did not see documentation added, can we add the required
> documentation for this.
>
> 8) The new test file added should be included in meson.build file
>

Thank you for reviewing the patch! These comments have been addressed
in the latest patch I've just submitted[1].

Regards,

[1] https://www.postgresql.org/message-id/CAD21AoB%3DRf-SASOJR2WqvWcrA5Q3S2oUBACVLdJPaA8x6EchBA%40mail.gmail.com

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


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-01 23:25:17
Message-ID: CAD21AoAficTcm9y-yFMmeGZ+8u8n1AOnuzK=fPCJXvzxPz0nZA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Jul 28, 2025 at 10:02 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Fri, Jul 25, 2025 at 11:45 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > Thank you for testing the patch!
> >
> > I've reworked the locking part in the patch. The attached v4 patch
> > should address all review comments including your previous
> > comments[1].
> >
>
> Thank You for the patch. I have not reviewed fully, but please find
> few comments:
>
> 1)
> CreateReplicationSlot():
>
> Assert(cmd->kind == REPLICATION_KIND_LOGICAL);
> + EnsureLogicalDecodingEnabled();
> CheckLogicalDecodingRequirements();
> ReplicationSlotCreate(...);
>
> We may have another race-condition here. We have
> EnsureLogicalDecodingEnabled() before ReplicationSlotCreate(). It
> means we are enabling logical-decoding before incrementing
> LogicalDecodingCtl->n_logical_slots. So before we increment
> LogicalDecodingCtl->n_logical_slots through ReplicationSlotCreate(),
> another session may try to meanwhile drop the logical slot (another
> one and last one), and thus it may end up disabling logical-decoding
> as it will find n_logical_slots as 0.
>
> Steps:
> a) Create logical slot logical_slot1 on primary.
> b) Create publication pub1.
> c) During Create-sub on subscriber, stop walsender after
> EnsureLogicalDecodingEnabled() by attaching debugger.
> d) Drop logical_slot1 on primary.
> e) Release the walsender debugger.

True. EnsureLogicalDecodingEnabled() has to be called after creating a
logical replication slot in order to reliably enable logical decoding.

>
>
> 2)
> create_logical_replication_slot:
>
> ReplicationSlotCreate(name, true
> ....
> + EnsureLogicalDecodingEnabled();
> + CheckLogicalDecodingRequirements();
>
> Earlier we had CheckLogicalDecodingRequirements() before we actually
> created the slot. Now we had it after slot-creation. It makes sense to
> do Logical-Decoding related checks post EnsureLogicalDecodingEnabled,
> but 'CheckSlotRequirements' should be done prior to slot-creation.
> Otherwise we will end up creating the slot and later dropping it when
> it should not have been created in the first place (for say wal_level
> < replica).
>
>
> 3)
> + EnsureLogicalDecodingEnabled();
> +
>
> We can get rid of this from slotsync as this is no-op on standby
>
>
> 4)
> pg_sync_replication_slots()
> if (!RecoveryInProgress())
> ereport(ERROR,
>
> errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> errmsg("replication slots can only be
> synchronized to a standby server"));
>
> + EnsureLogicalDecodingEnabled();
>
> This API is called on standby alone, so EnsureLogicalDecodingEnabled
> is not needed here either.

Thank you for reviewing the patch! Agree with these comments. They
have been addressed in the latest patch I've just submitted[1].

Regards,

[1] https://www.postgresql.org/message-id/CAD21AoB%3DRf-SASOJR2WqvWcrA5Q3S2oUBACVLdJPaA8x6EchBA%40mail.gmail.com
--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-04 10:38:35
Message-ID: CAJpy0uCR3xzsQy+60tG-OZtK3SWGFG+G1g1e0mvgYgPbC_vavA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Sat, Aug 2, 2025 at 4:53 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Thu, Jul 31, 2025 at 5:00 AM Hayato Kuroda (Fujitsu)
> <kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
> >
> > Dear Sawada-san,
> >
> > > I thought we could fix this issue by checking the number of in-use
> > > logical slots while holding ReplicationSlotControlLock and
> > > LogicalDecodingControlLock, but it seems we need to deal with another
> > > race condition too between backends and startup processes at the end
> > > of recovery.
> > >
> > > Currently the backend skips controlling logical decoding status if the
> > > server is in recovery (by checking RecoveryInProgress()), but it's
> > > possible that a backend process tries to drop a logical slot after the
> > > startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
> > > before accepting writes.
> >
> > Right. I also verified on local and found that
> > ReplicationSlotDropAcquired()->DisableLogicalDecodingIfNecessary() sometimes
> > skips to modify the status because RecoveryInProgress is still false.
> >
> > > In this case, the backend ends up not
> > > disabling logical decoding and it remains enabled. I think we would
> > > somehow need to delay the logical decoding status change in this
> > > period until the recovery completes.
> >
> > My primitive idea was to 1) keep startup acquiring the lock till end of recovery
> > and 2) DisableLogicalDecodingIfNecessary() acquires lock before checking the
> > recovery status, but it could not work well. Not sure but WaitForProcSignalBarrier()
> > stucked if the process acquired LogicalDecodingControlLock lock....
>
> I think that it's not realistic to keep holding a lwlock until the
> recovery actually completes because we perform a checkpoint after
> that.
>
> In the latest version patch I attached, I introduce a flag on shared
> memory to delay any logical decoding status change until the recovery
> completes. The implementation got more complex than I expected but I
> don't have a better idea. I'm open to other approaches. Also, I
> incorporated all comments I got so far[1][2][3] and updated the
> documentation.
>

Yes, it is slightly complex, I will put more thoughts into it. That
said, I do have a related scenario in mind concerning the recent fix,
where we might still end up with an incorrect effective_wal_level
after promotion.

Say primary has 'wal_level'=replica and standby has
'wal_level'=logical. Since there are no slots on standby
'effective_wal_level' will still be replica. Now I created a slot both
on primary and standby making 'effective_wal_level'=logical. Now, when
the standby is promoted and the slot is dropped immediately after
UpdateLogicalDecodingStatusEndOfRecovery() releases the lock, we still
expect the effective_wal_level on the promoted standby (now the
primary) to remain logical, since its configured 'wal_level' is
logical and it has become the primary. But I think that may not be the
case because 'DisableLogicalDecodingIfNecessary-->start_logical_decoding_status_change()'
does not consider original wal_level on promoted standby in
retrial-attempt. I feel 'retry' should be above ' wal_level ==
WAL_LEVEL_LOGICAL' check in below code snippet:

+static bool
+start_logical_decoding_status_change(bool new_status)
+{
+ /*
+ * On the primary with 'logical' WAL level, we can skip logical decoding
+ * status change as it's always enabled. On standbys, we need to check the
+ * status on shared memory propagated from the primary and might handle
+ * status change delay.
+ */
+ if (!RecoveryInProgress() && wal_level == WAL_LEVEL_LOGICAL)
+ return false;
+
+retry:
+

Please note that I could not reproduce this scenario because as soon
as I put sleep or injection-point in
UpdateLogicalDecodingStatusEndOfRecovery(), I hit some ProcSignal
Barriers issue i.e. it never completes even when sleep is over. I get
this: 'LOG: still waiting for backend with PID 162838 to accept
ProcSignalBarrier'.

Please let me know if my understanding is not correct above.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-04 23:43:26
Message-ID: CAD21AoBg71Q=FC2nmjW_RbS8At6_ohvx=MO=mG+r0O8dfM3MDw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Mon, Aug 4, 2025 at 3:38 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Sat, Aug 2, 2025 at 4:53 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Thu, Jul 31, 2025 at 5:00 AM Hayato Kuroda (Fujitsu)
> > <kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
> > >
> > > Dear Sawada-san,
> > >
> > > > I thought we could fix this issue by checking the number of in-use
> > > > logical slots while holding ReplicationSlotControlLock and
> > > > LogicalDecodingControlLock, but it seems we need to deal with another
> > > > race condition too between backends and startup processes at the end
> > > > of recovery.
> > > >
> > > > Currently the backend skips controlling logical decoding status if the
> > > > server is in recovery (by checking RecoveryInProgress()), but it's
> > > > possible that a backend process tries to drop a logical slot after the
> > > > startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
> > > > before accepting writes.
> > >
> > > Right. I also verified on local and found that
> > > ReplicationSlotDropAcquired()->DisableLogicalDecodingIfNecessary() sometimes
> > > skips to modify the status because RecoveryInProgress is still false.
> > >
> > > > In this case, the backend ends up not
> > > > disabling logical decoding and it remains enabled. I think we would
> > > > somehow need to delay the logical decoding status change in this
> > > > period until the recovery completes.
> > >
> > > My primitive idea was to 1) keep startup acquiring the lock till end of recovery
> > > and 2) DisableLogicalDecodingIfNecessary() acquires lock before checking the
> > > recovery status, but it could not work well. Not sure but WaitForProcSignalBarrier()
> > > stucked if the process acquired LogicalDecodingControlLock lock....
> >
> > I think that it's not realistic to keep holding a lwlock until the
> > recovery actually completes because we perform a checkpoint after
> > that.
> >
> > In the latest version patch I attached, I introduce a flag on shared
> > memory to delay any logical decoding status change until the recovery
> > completes. The implementation got more complex than I expected but I
> > don't have a better idea. I'm open to other approaches. Also, I
> > incorporated all comments I got so far[1][2][3] and updated the
> > documentation.
> >
>
> Yes, it is slightly complex, I will put more thoughts into it. That
> said, I do have a related scenario in mind concerning the recent fix,
> where we might still end up with an incorrect effective_wal_level
> after promotion.
>
> Say primary has 'wal_level'=replica and standby has
> 'wal_level'=logical. Since there are no slots on standby
> 'effective_wal_level' will still be replica. Now I created a slot both
> on primary and standby making 'effective_wal_level'=logical. Now, when
> the standby is promoted and the slot is dropped immediately after
> UpdateLogicalDecodingStatusEndOfRecovery() releases the lock, we still
> expect the effective_wal_level on the promoted standby (now the
> primary) to remain logical, since its configured 'wal_level' is
> logical and it has become the primary. But I think that may not be the
> case because 'DisableLogicalDecodingIfNecessary-->start_logical_decoding_status_change()'
> does not consider original wal_level on promoted standby in
> retrial-attempt. I feel 'retry' should be above ' wal_level ==
> WAL_LEVEL_LOGICAL' check in below code snippet:
>
> +static bool
> +start_logical_decoding_status_change(bool new_status)
> +{
> + /*
> + * On the primary with 'logical' WAL level, we can skip logical decoding
> + * status change as it's always enabled. On standbys, we need to check the
> + * status on shared memory propagated from the primary and might handle
> + * status change delay.
> + */
> + if (!RecoveryInProgress() && wal_level == WAL_LEVEL_LOGICAL)
> + return false;
> +
> +retry:
> +
>
> Please note that I could not reproduce this scenario because as soon
> as I put sleep or injection-point in
> UpdateLogicalDecodingStatusEndOfRecovery(), I hit some ProcSignal
> Barriers issue i.e. it never completes even when sleep is over. I get
> this: 'LOG: still waiting for backend with PID 162838 to accept
> ProcSignalBarrier'.

Thank you for the comment! I think you're right. That check should be
done after 'retry'. WIll incorporate the change in the next version
patch.

Regards,

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


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-05 10:11:44
Message-ID: CAJpy0uAxe5cWY=WgsJyKAXNTv7H2QbmApX7gR8sA33bh+ZyLjQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Aug 5, 2025 at 5:14 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Mon, Aug 4, 2025 at 3:38 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Sat, Aug 2, 2025 at 4:53 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > >
> > > On Thu, Jul 31, 2025 at 5:00 AM Hayato Kuroda (Fujitsu)
> > > <kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
> > > >
> > > > Dear Sawada-san,
> > > >
> > > > > I thought we could fix this issue by checking the number of in-use
> > > > > logical slots while holding ReplicationSlotControlLock and
> > > > > LogicalDecodingControlLock, but it seems we need to deal with another
> > > > > race condition too between backends and startup processes at the end
> > > > > of recovery.
> > > > >
> > > > > Currently the backend skips controlling logical decoding status if the
> > > > > server is in recovery (by checking RecoveryInProgress()), but it's
> > > > > possible that a backend process tries to drop a logical slot after the
> > > > > startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
> > > > > before accepting writes.
> > > >
> > > > Right. I also verified on local and found that
> > > > ReplicationSlotDropAcquired()->DisableLogicalDecodingIfNecessary() sometimes
> > > > skips to modify the status because RecoveryInProgress is still false.
> > > >
> > > > > In this case, the backend ends up not
> > > > > disabling logical decoding and it remains enabled. I think we would
> > > > > somehow need to delay the logical decoding status change in this
> > > > > period until the recovery completes.
> > > >
> > > > My primitive idea was to 1) keep startup acquiring the lock till end of recovery
> > > > and 2) DisableLogicalDecodingIfNecessary() acquires lock before checking the
> > > > recovery status, but it could not work well. Not sure but WaitForProcSignalBarrier()
> > > > stucked if the process acquired LogicalDecodingControlLock lock....
> > >
> > > I think that it's not realistic to keep holding a lwlock until the
> > > recovery actually completes because we perform a checkpoint after
> > > that.
> > >
> > > In the latest version patch I attached, I introduce a flag on shared
> > > memory to delay any logical decoding status change until the recovery
> > > completes. The implementation got more complex than I expected but I
> > > don't have a better idea. I'm open to other approaches. Also, I
> > > incorporated all comments I got so far[1][2][3] and updated the
> > > documentation.
> > >
> >
> > Yes, it is slightly complex, I will put more thoughts into it. That
> > said, I do have a related scenario in mind concerning the recent fix,
> > where we might still end up with an incorrect effective_wal_level
> > after promotion.
> >
> > Say primary has 'wal_level'=replica and standby has
> > 'wal_level'=logical. Since there are no slots on standby
> > 'effective_wal_level' will still be replica. Now I created a slot both
> > on primary and standby making 'effective_wal_level'=logical. Now, when
> > the standby is promoted and the slot is dropped immediately after
> > UpdateLogicalDecodingStatusEndOfRecovery() releases the lock, we still
> > expect the effective_wal_level on the promoted standby (now the
> > primary) to remain logical, since its configured 'wal_level' is
> > logical and it has become the primary. But I think that may not be the
> > case because 'DisableLogicalDecodingIfNecessary-->start_logical_decoding_status_change()'
> > does not consider original wal_level on promoted standby in
> > retrial-attempt. I feel 'retry' should be above ' wal_level ==
> > WAL_LEVEL_LOGICAL' check in below code snippet:
> >
> > +static bool
> > +start_logical_decoding_status_change(bool new_status)
> > +{
> > + /*
> > + * On the primary with 'logical' WAL level, we can skip logical decoding
> > + * status change as it's always enabled. On standbys, we need to check the
> > + * status on shared memory propagated from the primary and might handle
> > + * status change delay.
> > + */
> > + if (!RecoveryInProgress() && wal_level == WAL_LEVEL_LOGICAL)
> > + return false;
> > +
> > +retry:
> > +
> >
> > Please note that I could not reproduce this scenario because as soon
> > as I put sleep or injection-point in
> > UpdateLogicalDecodingStatusEndOfRecovery(), I hit some ProcSignal
> > Barriers issue i.e. it never completes even when sleep is over. I get
> > this: 'LOG: still waiting for backend with PID 162838 to accept
> > ProcSignalBarrier'.
>
> Thank you for the comment! I think you're right. That check should be
> done after 'retry'. WIll incorporate the change in the next version
> patch.
>

Thanks.

1)

start_logical_decoding_status_change():

+ LWLockRelease(LogicalDecodingControlLock);
+
+ /* Mark the state transition is in-progress */
+ LogicalDecodingCtl->transition_in_progress = true;

I think we should set transition_in_progress before releasing lock,
else it may hit a race condition between create and drop slot and can
end up having a slot but with logical decoding disabled.

Steps:
1) create logical_slot1
2) drop logical slot1, hold the debugger immediately before setting
transition_in_progress start_logical_decoding_status_change()
3) create logical_slot2
4) release debugger held during drop.
5) now, we will have a slot but effective_wal_level will be replica.

2)
CheckLogicalDecodingRequirements has this change:

- if (wal_level < WAL_LEVEL_LOGICAL)
+ if (wal_level < WAL_LEVEL_REPLICA)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("logical decoding requires \"wal_level\" >= \"logical\"")));
+ errmsg("logical decoding requires \"wal_level\" >= \"replica\"")));

But we already have same wal_level check in CheckSlotRequirements:

if (wal_level < WAL_LEVEL_REPLICA)
ereport(ERROR,

(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("replication slots can only be
used if \"wal_level\" >= \"replica\"")));

Thus the change in CheckLogicalDecodingRequirements for 'wal_level <
WAL_LEVEL_REPLICA' will never be reached. Is it needed?

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-06 00:47:53
Message-ID: CAD21AoBofq-hc3cO=A8T8uugaFpLAEXXfa3eo0RFkB5aqzo8jA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Aug 5, 2025 at 3:11 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> On Tue, Aug 5, 2025 at 5:14 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> >
> > On Mon, Aug 4, 2025 at 3:38 AM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> > >
> > > On Sat, Aug 2, 2025 at 4:53 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > >
> > > > On Thu, Jul 31, 2025 at 5:00 AM Hayato Kuroda (Fujitsu)
> > > > <kuroda(dot)hayato(at)fujitsu(dot)com> wrote:
> > > > >
> > > > > Dear Sawada-san,
> > > > >
> > > > > > I thought we could fix this issue by checking the number of in-use
> > > > > > logical slots while holding ReplicationSlotControlLock and
> > > > > > LogicalDecodingControlLock, but it seems we need to deal with another
> > > > > > race condition too between backends and startup processes at the end
> > > > > > of recovery.
> > > > > >
> > > > > > Currently the backend skips controlling logical decoding status if the
> > > > > > server is in recovery (by checking RecoveryInProgress()), but it's
> > > > > > possible that a backend process tries to drop a logical slot after the
> > > > > > startup process calling UpdateLogicalDecodingStatusEndOfRecovery() and
> > > > > > before accepting writes.
> > > > >
> > > > > Right. I also verified on local and found that
> > > > > ReplicationSlotDropAcquired()->DisableLogicalDecodingIfNecessary() sometimes
> > > > > skips to modify the status because RecoveryInProgress is still false.
> > > > >
> > > > > > In this case, the backend ends up not
> > > > > > disabling logical decoding and it remains enabled. I think we would
> > > > > > somehow need to delay the logical decoding status change in this
> > > > > > period until the recovery completes.
> > > > >
> > > > > My primitive idea was to 1) keep startup acquiring the lock till end of recovery
> > > > > and 2) DisableLogicalDecodingIfNecessary() acquires lock before checking the
> > > > > recovery status, but it could not work well. Not sure but WaitForProcSignalBarrier()
> > > > > stucked if the process acquired LogicalDecodingControlLock lock....
> > > >
> > > > I think that it's not realistic to keep holding a lwlock until the
> > > > recovery actually completes because we perform a checkpoint after
> > > > that.
> > > >
> > > > In the latest version patch I attached, I introduce a flag on shared
> > > > memory to delay any logical decoding status change until the recovery
> > > > completes. The implementation got more complex than I expected but I
> > > > don't have a better idea. I'm open to other approaches. Also, I
> > > > incorporated all comments I got so far[1][2][3] and updated the
> > > > documentation.
> > > >
> > >
> > > Yes, it is slightly complex, I will put more thoughts into it. That
> > > said, I do have a related scenario in mind concerning the recent fix,
> > > where we might still end up with an incorrect effective_wal_level
> > > after promotion.
> > >
> > > Say primary has 'wal_level'=replica and standby has
> > > 'wal_level'=logical. Since there are no slots on standby
> > > 'effective_wal_level' will still be replica. Now I created a slot both
> > > on primary and standby making 'effective_wal_level'=logical. Now, when
> > > the standby is promoted and the slot is dropped immediately after
> > > UpdateLogicalDecodingStatusEndOfRecovery() releases the lock, we still
> > > expect the effective_wal_level on the promoted standby (now the
> > > primary) to remain logical, since its configured 'wal_level' is
> > > logical and it has become the primary. But I think that may not be the
> > > case because 'DisableLogicalDecodingIfNecessary-->start_logical_decoding_status_change()'
> > > does not consider original wal_level on promoted standby in
> > > retrial-attempt. I feel 'retry' should be above ' wal_level ==
> > > WAL_LEVEL_LOGICAL' check in below code snippet:
> > >
> > > +static bool
> > > +start_logical_decoding_status_change(bool new_status)
> > > +{
> > > + /*
> > > + * On the primary with 'logical' WAL level, we can skip logical decoding
> > > + * status change as it's always enabled. On standbys, we need to check the
> > > + * status on shared memory propagated from the primary and might handle
> > > + * status change delay.
> > > + */
> > > + if (!RecoveryInProgress() && wal_level == WAL_LEVEL_LOGICAL)
> > > + return false;
> > > +
> > > +retry:
> > > +
> > >
> > > Please note that I could not reproduce this scenario because as soon
> > > as I put sleep or injection-point in
> > > UpdateLogicalDecodingStatusEndOfRecovery(), I hit some ProcSignal
> > > Barriers issue i.e. it never completes even when sleep is over. I get
> > > this: 'LOG: still waiting for backend with PID 162838 to accept
> > > ProcSignalBarrier'.
> >
> > Thank you for the comment! I think you're right. That check should be
> > done after 'retry'. WIll incorporate the change in the next version
> > patch.
> >
>
> Thanks.
>

Thank you for reviewing the patch!

> 1)
>
> start_logical_decoding_status_change():
>
> + LWLockRelease(LogicalDecodingControlLock);
> +
> + /* Mark the state transition is in-progress */
> + LogicalDecodingCtl->transition_in_progress = true;
>
> I think we should set transition_in_progress before releasing lock,
> else it may hit a race condition between create and drop slot and can
> end up having a slot but with logical decoding disabled.

Ugh, you're right. It should be protected by the lwlock.

>
> 2)
> CheckLogicalDecodingRequirements has this change:
>
> - if (wal_level < WAL_LEVEL_LOGICAL)
> + if (wal_level < WAL_LEVEL_REPLICA)
> ereport(ERROR,
> (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> - errmsg("logical decoding requires \"wal_level\" >= \"logical\"")));
> + errmsg("logical decoding requires \"wal_level\" >= \"replica\"")));
>
>
> But we already have same wal_level check in CheckSlotRequirements:
>
> if (wal_level < WAL_LEVEL_REPLICA)
> ereport(ERROR,
>
> (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> errmsg("replication slots can only be
> used if \"wal_level\" >= \"replica\"")));
>
> Thus the change in CheckLogicalDecodingRequirements for 'wal_level <
> WAL_LEVEL_REPLICA' will never be reached. Is it needed?

No, I agree to remove it.

I've attached the updated version patch.

Regards,

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

Attachment Content-Type Size
v6-0001-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 86.9 KB

From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-06 03:51:27
Message-ID: CAJpy0uBNDSX8x9w=ZD8P_VrRBGXoyxuuGiT9ouzPoB=Rk-geuw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Aug 6, 2025 at 6:18 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
>
> I've attached the updated version patch.
>

Thank You for the patch. The patch does not apply to the latest head
due to conflict with slot-sync fix (commit-Id: 4614d53d).

thanks
Shveta


From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-06 06:23:12
Message-ID: CAJpy0uCC2n6V3tNdSX6M92sLLJqPfwfd0HZxTmK7Te0Qyd4ZEQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Please find a few comments on v6:

1)
+/*
+ * Initialize logical decoding status on shmem at server startup. This
+ * must be called ONCE during postmaster or standalone-backend startup,
+ * before initializing replication slots.
+ */
+void
+StartupLogicalDecodingStatus(bool last_status)

The comment says that it needs to be called 'before initializing
replication slots' but instead it is called after initializing
replication slots (i.e. after StartupReplicationSlots).

Also, can you please help me understand the need of
'StartupLogicalDecodingStatus' when we are doing
'UpdateLogicalDecodingStatusEndOfRecovery' later in StartupXLOG. Why
do we need to set last_status temporarily when the new status can be
different which will be set in
UpdateLogicalDecodingStatusEndOfRecovery

2)
CreatePublication() has this:

+ errmsg("logical decoding needs to be enabled to publish logical changes"),
+ errhint("Set \"wal_level\" to \"logical\" or create a logical
replication slot with \"replica\" \"wal_level\" before creating
subscriptions.")));

While rest of the places has this:

+ errhint("Set \"wal_level\" >= \"logical\" or create at least one
logical slot on the primary.")));

Shall we make these errhint consistent? Either all mention
'wal_level=replica' condition along with slot-creation part or none.

3)
xlog_decode():

+ case XLOG_LOGICAL_DECODING_STATUS_CHANGE:
/*
* This can occur only on a standby, as a primary would
- * not allow to restart after changing wal_level < logical
+ * not allow to restart after changing wal_level < replica
* if there is pre-existing logical slot.
*/
Assert(RecoveryInProgress());
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("logical decoding on standby requires \"wal_level\" >=
\"logical\" on the primary")));
+ errmsg("logical decoding must be enabled on the primary")));

Is the comment correct?
a)
XLOG_LOGICAL_DECODING_STATUS_CHANGE can be result of logical-slot drop
on primary and not necessarily making wal_level < replica

b)
I see that even standby does not allow to restart when changing
wal_level < replica as against what comment says. Have I understood
the intent correctly?

standby LOG:
FATAL: logical replication slot "failover_slot_st" exists, but
"wal_level" < "replica"
HINT: Change "wal_level" to be "replica" or higher.

4)
start_logical_decoding_status_change():
+ if (LogicalDecodingCtl->transition_in_progress)
+ {
+ LWLockRelease(LogicalDecodingControlLock);

read_logical_decoding_status_transition() takes care of checking
transition_in_progress, I think we missed to remove above from
start_logical_decoding_status_change().

5)
+ /* Return if we don't need to change the status */
+ if (LogicalDecodingCtl->logical_decoding_enabled == new_status)
+ {

Same with this code-logic in start_logical_decoding_status_change(),
we shall remove it.

6)
+ * If we're in recovery and the startup process is still taking
+ * responsibility to update the status, we cannot change.
+ */
+ if (!delay_status_change)
+ return false;
+

This comment is confusing as when in recovery, we can not change state
otherwise as well even if delay_status_change is false. IIUC, the
scenario can arise only during promotion, if so, shall we say:

"If we're in recovery and a state transition (e.g., promotion) is in
progress, wait for the transition to complete and retry on the new
primary. Otherwise, disallow the status change entirely, as a standby
cannot modify the logical decoding status."

7)
The name 'delay_status_change' does not indicate which status or the
intent of delay. More name options are: defer_logical_status_change,
wait_for_recovery_transition/completion,
recovery_transition_in_progress

8)
DisableLogicalDecodingIfNecessary():
+
+ /* Write the WAL to disable logical decoding on standbys too */
+ if (XLogStandbyInfoActive() && !recoveryInProgress)
+ {

Do we need 'recoveryInProgress' check here?
start_logical_decoding_status_change() has taken care of that.

9)
Comments atop DisableLogicalDecodingIfNecessary:

* This function expects to be called after dropping a possibly-last logical
* replication slot. Logical decoding can be disabled only when wal_level is set
* to 'replica' and there is no logical replication slot on the system.

The comment is not completely true, shall we amend the comment to say
something like:

This function is called after a logical slot is dropped, but it only
disables logical decoding on primary if it was the last remaining
logical slot and wal_level < logical. Otherwise, it performs no
action.

10)
When we try to create or drop a logical slot on standby, and if
delay_status_change is false, shall we immediately exit? Currently it
does a lot of checks including CheckLogicalSlotExists() which can be
completely avoided. I think it is worth having a quick
'RecoveryInProgress() && !delay_status_change' check in the beginning.

thanks
Shveta


From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: shveta malik <shveta(dot)malik(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-07 21:59:36
Message-ID: CAD21AoBX3tn4WUnhjy6LkDP1sX0-0YWjSF9WbN3N_Bt7nOsU=w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Aug 5, 2025 at 11:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
>
> Please find a few comments on v6:
>
> 1)
> +/*
> + * Initialize logical decoding status on shmem at server startup. This
> + * must be called ONCE during postmaster or standalone-backend startup,
> + * before initializing replication slots.
> + */
> +void
> +StartupLogicalDecodingStatus(bool last_status)
>
> The comment says that it needs to be called 'before initializing
> replication slots' but instead it is called after initializing
> replication slots (i.e. after StartupReplicationSlots).

Removed.

> Also, can you please help me understand the need of
> 'StartupLogicalDecodingStatus' when we are doing
> 'UpdateLogicalDecodingStatusEndOfRecovery' later in StartupXLOG. Why
> do we need to set last_status temporarily when the new status can be
> different which will be set in
> UpdateLogicalDecodingStatusEndOfRecovery

IIUC we need to initialize the logical decoding status with the status
we used to use when the server shutdown or when the basebackup was
taken. This status would be used during recovery and might be changed
by replaying the XLOG_LOGICAL_DECODING_STATUS_CHANGE record. At the
end of recovery, we update the status based on the server's wal_level
and the number of logical replication slots so the new status could be
different from the status used during the recovery.

>
>
> 2)
> CreatePublication() has this:
>
> + errmsg("logical decoding needs to be enabled to publish logical changes"),
> + errhint("Set \"wal_level\" to \"logical\" or create a logical
> replication slot with \"replica\" \"wal_level\" before creating
> subscriptions.")));
>
> While rest of the places has this:
>
> + errhint("Set \"wal_level\" >= \"logical\" or create at least one
> logical slot on the primary.")));
>
> Shall we make these errhint consistent? Either all mention
> 'wal_level=replica' condition along with slot-creation part or none.

Fixed.

>
>
> 3)
> xlog_decode():
>
> + case XLOG_LOGICAL_DECODING_STATUS_CHANGE:
> /*
> * This can occur only on a standby, as a primary would
> - * not allow to restart after changing wal_level < logical
> + * not allow to restart after changing wal_level < replica
> * if there is pre-existing logical slot.
> */
> Assert(RecoveryInProgress());
> ereport(ERROR,
> (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> - errmsg("logical decoding on standby requires \"wal_level\" >=
> \"logical\" on the primary")));
> + errmsg("logical decoding must be enabled on the primary")));
>
> Is the comment correct?
>
> a)
> XLOG_LOGICAL_DECODING_STATUS_CHANGE can be result of logical-slot drop
> on primary and not necessarily making wal_level < replica
>
> b)
> I see that even standby does not allow to restart when changing
> wal_level < replica as against what comment says. Have I understood
> the intent correctly?
>
> standby LOG:
> FATAL: logical replication slot "failover_slot_st" exists, but
> "wal_level" < "replica"
> HINT: Change "wal_level" to be "replica" or higher.

I think I don't get your point. The comment looks correct to me.

On a primary server, a logical slot can only decode WAL records that
were generated while that slot existed. A
XLOG_LOGICAL_DECODING_STATUS_CHANGE record with logical_decoding=false
is generated in two cases: after the last logical slot is dropped, or
when the server starts with no logical slot and wal_level<='replica'.
In either case, no logical slots can exist that would be able to
decode these WAL records. However, on standby servers, it is possible
to decode these XLOG_LOGICAL_DECODING_STATUS_CHANGE records with
logical_decoding=false, as standbys can decode WAL records
independently of the primary.

>
>
> 4)
> start_logical_decoding_status_change():
> + if (LogicalDecodingCtl->transition_in_progress)
> + {
> + LWLockRelease(LogicalDecodingControlLock);
>
> read_logical_decoding_status_transition() takes care of checking
> transition_in_progress, I think we missed to remove above from
> start_logical_decoding_status_change().

Fixed.

>
>
> 5)
> + /* Return if we don't need to change the status */
> + if (LogicalDecodingCtl->logical_decoding_enabled == new_status)
> + {
>
> Same with this code-logic in start_logical_decoding_status_change(),
> we shall remove it.

Fixed.

>
> 6)
> + * If we're in recovery and the startup process is still taking
> + * responsibility to update the status, we cannot change.
> + */
> + if (!delay_status_change)
> + return false;
> +
>
> This comment is confusing as when in recovery, we can not change state
> otherwise as well even if delay_status_change is false. IIUC, the
> scenario can arise only during promotion, if so, shall we say:
>
> "If we're in recovery and a state transition (e.g., promotion) is in
> progress, wait for the transition to complete and retry on the new
> primary. Otherwise, disallow the status change entirely, as a standby
> cannot modify the logical decoding status."

Fixed.

>
> 7)
> The name 'delay_status_change' does not indicate which status or the
> intent of delay. More name options are: defer_logical_status_change,
> wait_for_recovery_transition/completion,
> recovery_transition_in_progress

I think 'delay' is used in other similar examples in PostgreSQL code.
For instance, we have DELAY_CHKPT_START/COMPLETE/IN_COMMIT that are
set by transactions to delay the actual checkpoint process until these
transactions complete certain operations. In our case, the flag is set
by the startup process in order to delay the actual status change
process by other processes until the recovery completes. Which is a
very similar usage so I believe 'delay' is appropriate here.

Regarding the 'status', I guess it's relatively obvious in this
context that the status indicates the logical decoding status so I'm
not sure that readers would confuse this name.

>
> 8)
> DisableLogicalDecodingIfNecessary():
> +
> + /* Write the WAL to disable logical decoding on standbys too */
> + if (XLogStandbyInfoActive() && !recoveryInProgress)
> + {
>
> Do we need 'recoveryInProgress' check here?
> start_logical_decoding_status_change() has taken care of that.

Removed.

>
> 9)
> Comments atop DisableLogicalDecodingIfNecessary:
>
> * This function expects to be called after dropping a possibly-last logical
> * replication slot. Logical decoding can be disabled only when wal_level is set
> * to 'replica' and there is no logical replication slot on the system.
>
> The comment is not completely true, shall we amend the comment to say
> something like:
>
> This function is called after a logical slot is dropped, but it only
> disables logical decoding on primary if it was the last remaining
> logical slot and wal_level < logical. Otherwise, it performs no
> action.

Thank you for the suggestion. I modified the comment based on the suggestion

>
> 10)
> When we try to create or drop a logical slot on standby, and if
> delay_status_change is false, shall we immediately exit? Currently it
> does a lot of checks including CheckLogicalSlotExists() which can be
> completely avoided. I think it is worth having a quick
> 'RecoveryInProgress() && !delay_status_change' check in the beginning.

Yeah, we can simplify the start_logical_decoding_status_change() logic more.

I've attached the updated patch.

Regards,

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

Attachment Content-Type Size
v7-0001-Enable-logical-decoding-dynamically-based-on-logi.patch application/octet-stream 87.1 KB

From: shveta malik <shveta(dot)malik(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, shveta malik <shveta(dot)malik(at)gmail(dot)com>
Subject: Re: POC: enable logical decoding when wal_level = 'replica' without a server restart
Date: 2025-08-08 03:21:13
Message-ID: CAJpy0uCSM9Go1mHp58w504MEfFEUqwu6vHfDwNnn-SobnQaZig@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, Aug 8, 2025 at 3:30 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> On Tue, Aug 5, 2025 at 11:23 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > Please find a few comments on v6:
> >
> > 1)
> > +/*
> > + * Initialize logical decoding status on shmem at server startup. This
> > + * must be called ONCE during postmaster or standalone-backend startup,
> > + * before initializing replication slots.
> > + */
> > +void
> > +StartupLogicalDecodingStatus(bool last_status)
> >
> > The comment says that it needs to be called 'before initializing
> > replication slots' but instead it is called after initializing
> > replication slots (i.e. after StartupReplicationSlots).
>
> Removed.
>
> > Also, can you please help me understand the need of
> > 'StartupLogicalDecodingStatus' when we are doing
> > 'UpdateLogicalDecodingStatusEndOfRecovery' later in StartupXLOG. Why
> > do we need to set last_status temporarily when the new status can be
> > different which will be set in
> > UpdateLogicalDecodingStatusEndOfRecovery
>
> IIUC we need to initialize the logical decoding status with the status
> we used to use when the server shutdown or when the basebackup was
> taken. This status would be used during recovery and might be changed
> by replaying the XLOG_LOGICAL_DECODING_STATUS_CHANGE record. At the
> end of recovery, we update the status based on the server's wal_level
> and the number of logical replication slots so the new status could be
> different from the status used during the recovery.
>

Okay.

> >
> >
> > 2)
> > CreatePublication() has this:
> >
> > + errmsg("logical decoding needs to be enabled to publish logical changes"),
> > + errhint("Set \"wal_level\" to \"logical\" or create a logical
> > replication slot with \"replica\" \"wal_level\" before creating
> > subscriptions.")));
> >
> > While rest of the places has this:
> >
> > + errhint("Set \"wal_level\" >= \"logical\" or create at least one
> > logical slot on the primary.")));
> >
> > Shall we make these errhint consistent? Either all mention
> > 'wal_level=replica' condition along with slot-creation part or none.
>
> Fixed.
>
> >
> >
> > 3)
> > xlog_decode():
> >
> > + case XLOG_LOGICAL_DECODING_STATUS_CHANGE:
> > /*
> > * This can occur only on a standby, as a primary would
> > - * not allow to restart after changing wal_level < logical
> > + * not allow to restart after changing wal_level < replica
> > * if there is pre-existing logical slot.
> > */
> > Assert(RecoveryInProgress());
> > ereport(ERROR,
> > (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> > - errmsg("logical decoding on standby requires \"wal_level\" >=
> > \"logical\" on the primary")));
> > + errmsg("logical decoding must be enabled on the primary")));
> >
> > Is the comment correct?
> >
> > a)
> > XLOG_LOGICAL_DECODING_STATUS_CHANGE can be result of logical-slot drop
> > on primary and not necessarily making wal_level < replica
> >
> > b)
> > I see that even standby does not allow to restart when changing
> > wal_level < replica as against what comment says. Have I understood
> > the intent correctly?
> >
> > standby LOG:
> > FATAL: logical replication slot "failover_slot_st" exists, but
> > "wal_level" < "replica"
> > HINT: Change "wal_level" to be "replica" or higher.
>
> I think I don't get your point. The comment looks correct to me.
>
> On a primary server, a logical slot can only decode WAL records that
> were generated while that slot existed. A
> XLOG_LOGICAL_DECODING_STATUS_CHANGE record with logical_decoding=false
> is generated in two cases: after the last logical slot is dropped, or
> when the server starts with no logical slot and wal_level<='replica'.
> In either case, no logical slots can exist that would be able to
> decode these WAL records. However, on standby servers, it is possible
> to decode these XLOG_LOGICAL_DECODING_STATUS_CHANGE records with
> logical_decoding=false, as standbys can decode WAL records
> independently of the primary.
>

Okay, I see your point. Thanks for explaining.

> >
> >
> > 4)
> > start_logical_decoding_status_change():
> > + if (LogicalDecodingCtl->transition_in_progress)
> > + {
> > + LWLockRelease(LogicalDecodingControlLock);
> >
> > read_logical_decoding_status_transition() takes care of checking
> > transition_in_progress, I think we missed to remove above from
> > start_logical_decoding_status_change().
>
> Fixed.
>
> >
> >
> > 5)
> > + /* Return if we don't need to change the status */
> > + if (LogicalDecodingCtl->logical_decoding_enabled == new_status)
> > + {
> >
> > Same with this code-logic in start_logical_decoding_status_change(),
> > we shall remove it.
>
> Fixed.
>
> >
> > 6)
> > + * If we're in recovery and the startup process is still taking
> > + * responsibility to update the status, we cannot change.
> > + */
> > + if (!delay_status_change)
> > + return false;
> > +
> >
> > This comment is confusing as when in recovery, we can not change state
> > otherwise as well even if delay_status_change is false. IIUC, the
> > scenario can arise only during promotion, if so, shall we say:
> >
> > "If we're in recovery and a state transition (e.g., promotion) is in
> > progress, wait for the transition to complete and retry on the new
> > primary. Otherwise, disallow the status change entirely, as a standby
> > cannot modify the logical decoding status."
>
> Fixed.
>
> >
> > 7)
> > The name 'delay_status_change' does not indicate which status or the
> > intent of delay. More name options are: defer_logical_status_change,
> > wait_for_recovery_transition/completion,
> > recovery_transition_in_progress
>
> I think 'delay' is used in other similar examples in PostgreSQL code.
> For instance, we have DELAY_CHKPT_START/COMPLETE/IN_COMMIT that are
> set by transactions to delay the actual checkpoint process until these
> transactions complete certain operations. In our case, the flag is set
> by the startup process in order to delay the actual status change
> process by other processes until the recovery completes. Which is a
> very similar usage so I believe 'delay' is appropriate here.
>
> Regarding the 'status', I guess it's relatively obvious in this
> context that the status indicates the logical decoding status so I'm
> not sure that readers would confuse this name.
>

Okay, we can retain the same.

> >
> > 8)
> > DisableLogicalDecodingIfNecessary():
> > +
> > + /* Write the WAL to disable logical decoding on standbys too */
> > + if (XLogStandbyInfoActive() && !recoveryInProgress)
> > + {
> >
> > Do we need 'recoveryInProgress' check here?
> > start_logical_decoding_status_change() has taken care of that.
>
> Removed.
>
> >
> > 9)
> > Comments atop DisableLogicalDecodingIfNecessary:
> >
> > * This function expects to be called after dropping a possibly-last logical
> > * replication slot. Logical decoding can be disabled only when wal_level is set
> > * to 'replica' and there is no logical replication slot on the system.
> >
> > The comment is not completely true, shall we amend the comment to say
> > something like:
> >
> > This function is called after a logical slot is dropped, but it only
> > disables logical decoding on primary if it was the last remaining
> > logical slot and wal_level < logical. Otherwise, it performs no
> > action.
>
> Thank you for the suggestion. I modified the comment based on the suggestion
>
> >
> > 10)
> > When we try to create or drop a logical slot on standby, and if
> > delay_status_change is false, shall we immediately exit? Currently it
> > does a lot of checks including CheckLogicalSlotExists() which can be
> > completely avoided. I think it is worth having a quick
> > 'RecoveryInProgress() && !delay_status_change' check in the beginning.
>
> Yeah, we can simplify the start_logical_decoding_status_change() logic more.
>
> I've attached the updated patch.
>
> Regards,
>
> --
> Masahiko Sawada
> Amazon Web Services: https://aws.amazon.com