Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1u7PO6-00Fmv6-ET for pgsql-bugs@arkaria.postgresql.org; Wed, 23 Apr 2025 01:59:03 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1u7PO4-002HQT-Ba for pgsql-bugs@arkaria.postgresql.org; Wed, 23 Apr 2025 01:58:57 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1u7PO3-002HQL-4r for pgsql-bugs@lists.postgresql.org; Wed, 23 Apr 2025 01:58:56 +0000 Received: from fhigh-b3-smtp.messagingengine.com ([202.12.124.154]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1u7PNz-001S9x-0K for pgsql-bugs@lists.postgresql.org; Wed, 23 Apr 2025 01:58:55 +0000 Received: from phl-compute-07.internal (phl-compute-07.phl.internal [10.202.2.47]) by mailfhigh.stl.internal (Postfix) with ESMTP id DC54D2540183; Tue, 22 Apr 2025 21:58:49 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-07.internal (MEProxy); Tue, 22 Apr 2025 21:58:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eulerto.com; h= cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm3; t=1745373529; x=1745459929; bh=nW44p6tHZ+ GxxpOZN+jBeHCi5X+e1x5uOJtBdIS6bpw=; b=R5996wYj1vvbtKp8Rg3FW/QDZq xiS897BNCPZTZtNyfaSZU/2Kq69bI7mMrUMESOLeN9KBJ8uIlVqIO7EgrD4oxD1f ymjJvmopuNKE2gnVZcFy2baVEhWkRDFiMfBHi0pi3urEkhImDfSm146az9ahco1u rvB1LZb08yvMeb82jJfevNontu+FF1YvHhTz+Pt4XIl7Nt76U64tiajuPNEl02V9 ELKFFVhvzm8uy8mMnR6Jlbzg0z1XbM1VDckoyA7uOWmHzTTTImZQXHeq3fMZvr9O jxi+HeNHPijwCJ8mPjuRprcHdToQtKjf18NFptymPljEBne6mNHmyX7SNbcg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1745373529; x=1745459929; bh=nW44p6tHZ+GxxpOZN+jBeHCi5X+e1x5uOJt BdIS6bpw=; b=KlrbCt5LAFWFRhWcJI3d/X2drs9xslNjtZ1MDX/iqErRyVl+aSL HN4GHr9RNaLHINaP7ouIox8d+CpVG3R1XIxVL9x1gxJHJi7JMoCCHMfDUXyCqR9G cVAs0Fkt8FXKSNeUJVTUkWNneEhK+CtJ0nX5Ne0ye6y1umxMzp3mUeojS3qh/DF3 fEDTOz0xj0CgIRu3mLUjLlYdFg0XsODsXHkuDMrnq9MI6NiD+NNNk5KQCwS3n1nI 8XxpHUPWW0fPA2VqBFRTGkiarVrIuISNQdKViGBtox6fy5rCner8Bsd79PPLq8aY HpYC/pb+W2EWr7W4TKtgWh6vJMRAHfE15RQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvgeehfeehucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefogg ffhffvkfgjfhfutgesrgdtreerredttdenucfhrhhomhepfdfguhhlvghrucfvrghvvghi rhgrfdcuoegvuhhlvghrsegvuhhlvghrthhordgtohhmqeenucggtffrrghtthgvrhhnpe duheeuleeifefhvedthfefleffledvvdevueeufeetleeuvedviefhudekhfeggeenucff ohhmrghinhepghhithhhuhgsrdgtohhmpdgvnhhtvghrphhrihhsvggusgdrtghomhenuc evlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegvuhhlvghr segvuhhlvghrthhordgtohhmpdhnsggprhgtphhtthhopedvpdhmohguvgepshhmthhpoh huthdprhgtphhtthhopeguuhhffhhivghlugiirghnvgesghhmrghilhdrtghomhdprhgt phhtthhopehpghhsqhhlqdgsuhhgsheslhhishhtshdrphhoshhtghhrvghsqhhlrdhorh hg X-ME-Proxy: Feedback-ID: i0c21471d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id F37AD780069; Tue, 22 Apr 2025 21:58:48 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface MIME-Version: 1.0 X-ThreadId: T778282b004f53ae9 Date: Tue, 22 Apr 2025 22:57:53 -0300 From: "Euler Taveira" To: duffieldzane@gmail.com, pgsql-bugs@lists.postgresql.org Message-Id: <86e60caf-d994-4b97-b504-22db9c825c52@app.fastmail.com> In-Reply-To: <18897-d3db67535860dddb@postgresql.org> References: <18897-d3db67535860dddb@postgresql.org> Subject: Re: BUG #18897: Logical replication conflict after using pg_createsubscriber under heavy load Content-Type: multipart/alternative; boundary=2ad8e923d1f549008ffd5cf8c42c6a83 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --2ad8e923d1f549008ffd5cf8c42c6a83 Content-Type: text/plain Content-Transfer-Encoding: 7bit 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/ --2ad8e923d1f549008ffd5cf8c42c6a83 Content-Type: text/html Content-Transfer-Encoding: quoted-printable
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 lo= gical 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
confirm that the native logical replication implementation did not have= this
problem, and I've found that it might have a different p= roblem.

pg_createsubscriber uses a= different approach than pglogical. While pglogical
uses a res= tore point, pg_createsubscriber uses the LSN from the latest
r= eplication slot as a replication start point. The restore point approach= is
usually suitable to physical replication but might not cov= er all scenarios for
logical replication (such as when there a= re in progress transactions). Since
creating a logical replica= tion slot does find a consistent decoding start
point, it is a= natural choice to start the logical replication (that also needs
<= div>to find a decoding start point).

I should say that I've been ope= rating under the assumption that
pg_createsubscriber is design= ed for use on a replica for a *live* primary
database, if this= isn't correct then someone please let me know.
<= br>
pg_createsubscriber expects a physical replica that is pre= ferably stopped
before running it.

I have a script that I've b= een using to reproduce the issue (pasted at end
of email, beca= use this bug reporting page doesn't seem to support
attachment= s). It basically performs a loop that sets up a primary and a
= physical replica, generates some load, converts the replica to logical,<= /div>
waits, and makes sure the row counts are the same.

If I run your tests, it reports
$ NUM_THREADS=3D40 INSERT_WIDTH=3D1000 /tmp/logical_stress_t= est.sh
.
.

*** Successfully= started logical replica on port 5341.
*** ALL INSERT LOOPS FI= NISHED
SOURCE COUNT =3D  916000
DEST COUNT = ;  =3D  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_tab= le" -d test_db
count  
--------
= 916000
(1 row)

I also checked the dat= a

$ pg_dump -t test_table -p 5340 -d test_db -f= - | sort > /tmp/p.out
$ pg_dump -t test_table -p 5341 -d t= est_db -f - | sort > /tmp/r.out
$ diff -q /tmp/p.out /tmp/r= .out
$ echo $?
0

Your scrip= t 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_subscripti= on_sync routine
(Cluster.pm) before counting the rows. That's = what is used in the
pg_createsubscriber tests. It guarantees t= he subscriber has caught up.


--
Euler Taveira

--2ad8e923d1f549008ffd5cf8c42c6a83--