On Thu, May 28, 2026 at 2:09 AM Chao Li <li.evan.chao@gmail.com> wrote:
>
> Hi,
>
> While testing “Toggle logical decoding dynamically based on logical slot presence”, I hit an assertion failure with
concurrentlogical slot creation.
>
> This is a repo:
>
> 1. In session 1, attach the injection point locally and start creating a logical slot. The session blocks at
logical-decoding-activation:
> ```
> evantest=# set application_name = 'slot_a';
> SET
> evantest=# select injection_points_set_local();
> injection_points_set_local
> ----------------------------
>
> (1 row)
> evantest=# select injection_points_attach('logical-decoding-activation', 'wait');
> injection_points_attach
> -------------------------
>
> (1 row)
> evantest=# select pg_create_logical_replication_slot('slot_a', 'pgoutput');
> ```
>
> 2. In session 2, create another logical slot. This succeeds, and effective_wal_level becomes logical:
> ```
> evantest=# select pg_create_logical_replication_slot('slot_b', 'pgoutput');
> pg_create_logical_replication_slot
> ------------------------------------
> (slot_b,0/0902E418)
> (1 row)
>
> evantest=# show effective_wal_level;
> effective_wal_level
> ---------------------
> logical
> (1 row)
> ```
>
> 3. In session 2, cancel session 1 instead of waking it up:
> ```
> evantest=# select pg_cancel_backend(pid) from pg_stat_activity where application_name = 'slot_a';
> pg_cancel_backend
> -------------------
> t
> (1 row)
> ```
>
> Then the server hits this assertion:
Thank you for the report! I've confirmed the problem.
>
> I might be over thinking, but I just feel the safest fix is to make EnableLogicalDecoding() serialize. I tried
serializingwith LogicalDecodingControlLock and with a separate lock, but both approaches got deadlock around the
barrierwait. I ended up with adding an activation_in_progress flag in shared memory, protected by
LogicalDecodingControlLock,with a condition variable to wait for the active activation to finish.
>
> With this fix, rerunning the repro makes session 2 wait while session 1 is blocked at the injection point. After
cancelingsession 1 from session 3, session 2 continues, creates the slot successfully, and effective_wal_level becomes
logical.
This serialization idea is very similar to what we tried in older
version patches. While I've confirmed that the patch fixes the
reported issue, I'm somewhat concerned that it could introduce another
race condition as the patch adds a new mechanism.
I think that the complication stems from the fact that
abort_logical_decoding_activation() and DisableLogicalDecoding() clear
the xlog_logical_info flag in different ways. I guess it would be
simpler if we could delegate all the deactivation process including
clearing xlog_logical_info flag to DisableLogicalDecoding(). It would
allow the system to be in the state of xlog_logical_info == true and
logical_decoding_enabled = false, but if we change
DisableLogicalDecoding() to handle this case, the deactivation process
would become simpler.
> I didn’t include a test in this patch, as I wasn’t sure such a test would be desirable. If others think it is worth
adding,I can convert the repro into a TAP test.
I think we should have the tests.
I've attached the patch for the above idea including the regression
tests. Please review it.
Regards,
--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com