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

Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com>

From: "Hayato Kuroda (Fujitsu)" <kuroda.hayato@fujitsu.com>
To: "Hayato Kuroda (Fujitsu)" <kuroda.hayato@fujitsu.com>, 'Masahiko Sawada' <sawada.mshk@gmail.com>
Cc: shveta malik <shveta.malik@gmail.com>, Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>, Amit Kapila <amit.kapila16@gmail.com>, Shlok Kyal <shlok.kyal.oss@gmail.com>, Bertrand Drouvot <bertranddrouvot.pg@gmail.com>, PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2025-10-02T10:40:24Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Fix regression test failure when wal_level is set to minimal.

  2. Toggle logical decoding dynamically based on logical slot presence.

  3. Disallow server start with sync_replication_slots = on and wal_level < logical.

I found that after the fix I proposed [1], there is a possibility that effective_wal_level
could be logical after the promotion, even after the logical slots are dropped [2].
Steps:

0. Setup a streaming replication system, and both nodes had a replication slot
1. Attached to the startup and added a break at UpdateLogicalDecodingStatusEndOfRecovery
2. Sent a promotion request to the standby. Startup would stop
3. Established a connection to the standby.
4. Attached to the backend and added a break at ReplicationSlotDrop
5. Tried to drop the replication slot on the standby. Backend would stop
6. Moved the startup till WaitForProcSignalBarrier(). Note that allow_status_change
   was still off.
7. Detached from the backend process.
8. Detached from the startup process.

This can happen because UpdateLogicalDecodingStatusEndOfRecovery() decided to
keep wal_level logical, and upcoming DisableLogicalDecodingIfNecessary() cannot
disable it. allow_status_change should be true for the case.

I considered an approach not to release lock while waiting the ProcSignal, but
other processes cannot not read and update xlog_logical_info.

[1]: https://www.postgresql.org/message-id/OSCPR01MB14966B8F6F728F3FB4B05BFDBF5E7A%40OSCPR01MB14966.jpnprd01.prod.outlook.com
[2]
```
postgres=# SELECT pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 f
(1 row)

postgres=# SHOW effective_wal_level ;
 effective_wal_level 
---------------------
 logical
(1 row)

postgres=# SELECT count(*) FROM pg_replication_slots ;
 count 
-------
     0
(1 row)
```

Best regards,
Hayato Kuroda
FUJITSU LIMITED