Re: long-standing data loss bug in initial sync of logical replication
Nitin Motiani <nitinmotiani@google.com>
From: Nitin Motiani <nitinmotiani@google.com>
To: vignesh C <vignesh21@gmail.com>
Cc: Amit Kapila <amit.kapila16@gmail.com>,
Tomas Vondra <tomas.vondra@enterprisedb.com>, Andres Freund <andres@anarazel.de>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2024-07-18T10:17:26Z
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 typo in test file name added in commit 4909b38af0.
- 50b8ad30f754 18.0 landed
- d96206f259d6 17.5 landed
- 9987c94662c2 16.9 landed
- 90bc4523fd47 15.13 landed
- bb1bc9fa962e 14.18 landed
- 4164d6976316 13.21 landed
-
Fix data loss in logical replication.
- 247ee94150b6 13.21 landed
- 4909b38af034 18.0 landed
- cadaf0ac4637 17.5 landed
- 9a2f8b4f01d5 16.9 landed
- 9f21be08e884 15.13 landed
- 0434033e8bb5 14.18 landed
-
Avoid invalidating all RelationSyncCache entries on publication rename.
- 3abe9dc18892 18.0 cited
-
Remove obsolete RECHECK keyword completely
- 7da1bdc2c2f1 18.0 cited
-
Backport BackgroundPsql perl test module
- 187b8991f70f 16.4 cited
On Thu, Jul 18, 2024 at 3:30 PM Nitin Motiani <nitinmotiani@google.com> wrote: > > On Thu, Jul 18, 2024 at 3:25 PM Nitin Motiani <nitinmotiani@google.com> wrote: > > > > On Thu, Jul 18, 2024 at 3:05 PM Nitin Motiani <nitinmotiani@google.com> wrote: > > > > > > On Wed, Jul 17, 2024 at 5:25 PM vignesh C <vignesh21@gmail.com> wrote: > > > > > > > > I tested these scenarios, and as you expected, it throws an error for > > > > the create publication case: > > > > 2024-07-17 14:50:01.145 IST [481526] 481526 ERROR: could not receive > > > > data from WAL stream: ERROR: publication "pub1" does not exist > > > > CONTEXT: slot "sub1", output plugin "pgoutput", in the change > > > > callback, associated LSN 0/1510CD8 > > > > 2024-07-17 14:50:01.147 IST [481450] 481450 LOG: background worker > > > > "logical replication apply worker" (PID 481526) exited with exit code > > > > 1 > > > > > > > > The steps for this process are as follows: > > > > 1) Create tables in both the publisher and subscriber. > > > > 2) On the publisher: Create a replication slot. > > > > 3) On the subscriber: Create a subscription using the slot created by > > > > the publisher. > > > > 4) On the publisher: > > > > 4.a) Session 1: BEGIN; INSERT INTO T1; > > > > 4.b) Session 2: CREATE PUBLICATION FOR ALL TABLES > > > > 4.c) Session 1: COMMIT; > > > > > > > > Since we are throwing out a "publication does not exist" error, there > > > > is no inconsistency issue here. > > > > > > > > However, an issue persists with DROP ALL TABLES publication, where > > > > data continues to replicate even after the publication is dropped. > > > > This happens because the open transaction consumes the invalidation, > > > > causing the publications to be revalidated using old snapshot. As a > > > > result, both the open transactions and the subsequent transactions are > > > > getting replicated. > > > > > > > > We can reproduce this issue by following these steps in a logical > > > > replication setup with an "ALL TABLES" publication: > > > > On the publisher: > > > > Session 1: BEGIN; INSERT INTO T1 VALUES (val1); > > > > In another session on the publisher: > > > > Session 2: DROP PUBLICATION > > > > Back in Session 1 on the publisher: > > > > COMMIT; > > > > Finally, in Session 1 on the publisher: > > > > INSERT INTO T1 VALUES (val2); > > > > > > > > Even after dropping the publication, both val1 and val2 are still > > > > being replicated to the subscriber. This means that both the > > > > in-progress concurrent transaction and the subsequent transactions are > > > > being replicated. > > > > > > > > > > Hi, > > > > > > I tried the 'DROP PUBLICATION' command even for a publication with a > > > single table. And there also the data continues to get replicated. > > > > > > To test this, I did a similar experiment as the above but instead of > > > creating publication on all tables, I did it for one specific table. > > > > > > Here are the steps : > > > 1. Create table test_1 and test_2 on both the publisher and subscriber > > > instances. > > > 2. Create publication p for table test_1 on the publisher. > > > 3. Create a subscription s which subscribes to p. > > > 4. On the publisher > > > 4a) Session 1 : BEGIN; INSERT INTO test_1 VALUES(val1); > > > 4b) Session 2 : DROP PUBLICATION p; > > > 4c) Session 1 : Commit; > > > 5. On the publisher : INSERT INTO test_1 VALUES(val2); > > > > > > After these, when I check the subscriber, both val1 and val2 have been > > > replicated. I tried a few more inserts on publisher after this and > > > they all got replicated to the subscriber. Only after explicitly > > > creating a new publication p2 for test_1 on the publisher, the > > > replication stopped. Most likely because the create publication > > > command invalidated the cache. > > > > > > My guess is that this issue probably comes from the fact that > > > RemoveObjects in dropcmds.c doesn't do any special handling or > > > invalidation for the object drop command. > > > > > > > I checked further and I see that RemovePublicationById does do cache > > invalidation but it is only done in the scenario when the publication > > is on all tables. This is done without taking any locks. But for the > > other cases (eg. publication on one table), I don't see any cache > > invalidation in RemovePublicationById. That would explain why the > > replication kept happening for multiple transactions after the drop > > publication command in my example.. > > > > Sorry, I missed that for the individual table scenario, the > invalidation would happen in RemovePublicationRelById. That is > invalidating the cache for all relids. But this is also not taking any > locks. So that would explain why dropping the publication on a single > table doesn't invalidate the cache in an ongoing transaction. I'm not > sure why the replication kept happening even in subsequent > transactions. > > Either way I think the SRE lock should be taken for all relids in that > function also before the invalidations. > My apologies. I wasn't testing with the latest patch. I see this has already been done in the v6 patch file. Thanks & Regards Nitin Motiani Google