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: 'Masahiko Sawada' <sawada.mshk@gmail.com>
Cc: Shlok Kyal <shlok.kyal.oss@gmail.com>, Amit Kapila <amit.kapila16@gmail.com>, Bertrand Drouvot <bertranddrouvot.pg@gmail.com>, shveta malik <shveta.malik@gmail.com>, Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>, PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2025-08-27T12:07:53Z
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 →
-
Fix regression test failure when wal_level is set to minimal.
- 0de5f0d869d1 19 (unreleased) landed
-
Toggle logical decoding dynamically based on logical slot presence.
- 67c20979ce72 19 (unreleased) landed
-
Disallow server start with sync_replication_slots = on and wal_level < logical.
- 12da45742cfd 19 (unreleased) cited
Dear Sawada-san,
Thanks for updating the patch. Here are my comments.
xlog_desc()
```
else if (info == XLOG_LOGICAL_DECODING_STATUS_CHANGE)
{
bool enabled;
memcpy(&enabled, rec, sizeof(bool));
appendStringInfo(buf, enabled ? "true" : "false");
}
```
Per 2075ba9, appendStringInfoString() can be used if we do not have other messages.
logicalctl.h
```
extern void UpdateNumberOfLogicalSlots(bool incr);
```
This function is not implemented.
UpdateLogicalDecodingStatus()
```
elog(DEBUG1, "update logical decoding status to %d", new_status);
```
I prefer to use true/false instead of 1/0, thought?
xlog_redo()
```
/* Update the status on shared memory */
memcpy(&logical_decoding, XLogRecGetData(record), sizeof(bool));
UpdateLogicalDecodingStatus(logical_decoding, true);
if (InRecovery && InHotStandby)
{
if (!logical_decoding)
{
/*
* Invalidate logical slots if we are in hot standby and the
* primary disabled the logical decoding.
*/
InvalidateObsoleteReplicationSlots(RS_INVAL_WAL_LEVEL,
0, InvalidOid,
InvalidTransactionId);
```
Assuming that logical_decoding written in the WAL is false here, and a logical
replication slot is created just after that. In my experiments below happened:
1. startup process updated logical_decoding_enabled to false, at line 8652.
2. slotsync worker started to sync. Surprisingly, it created a (second) logical
slot and started logical decoding with fast_foward mode.
3. startup invalidated logical slots due to the wal_level. the slot created at
step2 was automatically dropped, because it was not sync-readly yet.
4. startup process shut down the slotsync worker.
5. start process read the STATUS_CHANGE record again, which has the value "true".
it requested to restart the sync worker.
6. restarted sync worker synchronize the slot again...
For me it works well but it is bit a strange because 1) logical decoding is
started even when effective_wal_level is false, and 2) the synced slot is
dropped once with below message:
```
LOG: terminating process 1474448 to release replication slot "test2"
DETAIL: Logical decoding on standby requires "wal_level" >= "logical" or at least one logical slot on the primary server.
CONTEXT: WAL redo at 0/030000B8 for XLOG/LOGICAL_DECODING_STATUS_CHANGE: false
ERROR: canceling statement due to conflict with recovery
DETAIL: User was using a logical replication slot that must be invalidated.
```
Can we stop the sync worker before updating the status? IIUC this is one of the
solution.
Best regards,
Hayato Kuroda
FUJITSU LIMITED