On Fri, Sep 5, 2025 at 8:21 AM Chao Li <li.evan.c...@gmail.com> wrote: > > I was doing some test about logical replication a few days ago. When I tried > to setup a logical replication on my Macbook. > > The basic workflow is simple: > > ``` > Step 1: edit postgresql.conf and set: > > wal_level = logical > max_replication_slots = 4 > max_wal_senders = 4 > > Step 2: create two databases for pub and sub > > % createdb pubdb > % createdb subdb > > Step 3: create a table in pubdb, and create a publication > > pubdb=# CREATE TABLE t (id int primary key, data text); > CREATE TABLE > > pubdb=# INSERT INTO t VALUES (1, 'hello from pub'); > INSERT 0 1 > > pubdb=# CREATE PUBLICATION mypub FOR TABLE t; > CREATE PUBLICATION > > Step 4: create the same table in subdb > > subdb=# CREATE TABLE t (id int primary key, data text); > CREATE TABLE > > Step 5: create subscription in subdb > > subdb=# CREATE SUBSCRIPTION mysub CONNECTION 'host=localhost dbname=pubdb' > PUBLICATION mypub; <==== stuck here > ``` > > In step 5, "CREATE SUBSCRIPTION" got stuck. Then I found the issue had been > discussed with [1] in 2017, but no more effort had been spent resolving the > issue. > > Then I investigated the root cause. Feels like this is a architectural > problem. Because both pubdb and subdb run in the same cluster, so they share > the same transaction id serial. > > In step 5, when subdb "CREATE SUBSCRIPTION", say the transaction id is 100, > what the backend worker process does is like: > > 1) start a xact (100) > 2) insert a tuple into pg_subscription > 3) request pub side to create a sub slot and wait for the result > 4) commit > > When the pub side receives the request to create a replication slot, it needs > to check no running transactions. However, xact 100 is running and waiting > for replication slot creation to finish. This is a deadlock, and the deadlock > exists only when pub and sub are in the same cluster. >
You can avoid this problem by creating a slot first on publisher with something like: postgres=# select pg_create_logical_replication_slot('s1', 'pgoutput', false, true); pg_create_logical_replication_slot ------------------------------------ (s1,0/01BFF178) (1 row) Then while creating subscription you can use the above created slot as follows: db1=# create subscription sub1 connection 'dbname=postgres' publication pub1 WITH(create_slot=false, slot_name='s1'); CREATE SUBSCRIPTION -- With Regards, Amit Kapila.