Re: BUG #18897: Logical replication conflict after using pg_createsubscriber under heavy load
Euler Taveira <euler@eulerto.com>
From: "Euler Taveira" <euler@eulerto.com>
To: duffieldzane@gmail.com, pgsql-bugs@lists.postgresql.org
Date: 2025-04-23T01:57:53Z
Lists: pgsql-bugs
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix duplicate transaction replay during pg_createsubscriber.
- e1c3654839e4 19 (unreleased) landed
- 33f74b806ce3 18.0 landed
- 967309116f0d 17.6 landed
-
pg_createsubscriber: Fix an unpredictable recovery wait time.
- 03b08c8f5f3e 18.0 cited
On Wed, Apr 16, 2025, at 8:14 PM, PG Bug reporting form wrote: > I'm in the process of converting our databases from pglogical logical > replication to the native logical replication implementation on PostgreSQL > 17. One of the bugs we encountered and had to work around with pglogical was > the plugin dropping records while converting to a streaming replica to > logical via pglogical_create_subscriber (reported > https://github.com/2ndQuadrant/pglogical/issues/349). I was trying to > confirm that the native logical replication implementation did not have this > problem, and I've found that it might have a different problem. pg_createsubscriber uses a different approach than pglogical. While pglogical uses a restore point, pg_createsubscriber uses the LSN from the latest replication slot as a replication start point. The restore point approach is usually suitable to physical replication but might not cover all scenarios for logical replication (such as when there are in progress transactions). Since creating a logical replication slot does find a consistent decoding start point, it is a natural choice to start the logical replication (that also needs to find a decoding start point). > I should say that I've been operating under the assumption that > pg_createsubscriber is designed for use on a replica for a *live* primary > database, if this isn't correct then someone please let me know. pg_createsubscriber expects a physical replica that is preferably stopped before running it. > I have a script that I've been using to reproduce the issue (pasted at end > of email, because this bug reporting page doesn't seem to support > attachments). It basically performs a loop that sets up a primary and a > physical replica, generates some load, converts the replica to logical, > waits, and makes sure the row counts are the same. If I run your tests, it reports $ NUM_THREADS=40 INSERT_WIDTH=1000 /tmp/logical_stress_test.sh . . *** Successfully started logical replica on port 5341. *** ALL INSERT LOOPS FINISHED SOURCE COUNT = 916000 DEST COUNT = 768000 ERROR: record count mismatch but after some time $ psql -X -p 5340 -c "SELECT count(f1) FROM test_table" -d test_db count -------- 916000 (1 row) $ psql -X -p 5341 -c "SELECT count(f1) FROM test_table" -d test_db count -------- 916000 (1 row) I also checked the data $ pg_dump -t test_table -p 5340 -d test_db -f - | sort > /tmp/p.out $ pg_dump -t test_table -p 5341 -d test_db -f - | sort > /tmp/r.out $ diff -q /tmp/p.out /tmp/r.out $ echo $? 0 Your script is not waiting enough time until it applies the backlog. Unless, you are seeing a different symptom, there is no bug. You should have used something similar to wait_for_subscription_sync routine (Cluster.pm) before counting the rows. That's what is used in the pg_createsubscriber tests. It guarantees the subscriber has caught up. -- Euler Taveira EDB https://www.enterprisedb.com/