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: Amit Kapila <amit.kapila16@gmail.com>, Bertrand Drouvot <bertranddrouvot.pg@gmail.com>, Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>, PostgreSQL-development <pgsql-hackers@postgresql.org>, shveta malik <shveta.malik@gmail.com>
Date: 2025-07-30T07:22:36Z
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, 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