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-18T09:55:05Z
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: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.. Thanks & Regards Nitin Motiani Google