Re: row filtering for logical replication
Greg Nancarrow <gregn4422@gmail.com>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Release cache tuple when no longer needed
- ed0fbc8e5ac9 15.0 landed
-
Add some additional tests for row filters in logical replication.
- ceb57afd3ce1 15.0 landed
-
Fix one of the tests introduced in commit 52e4f0cd47.
- cfb4e209ec15 15.0 landed
-
Allow specifying row filters for logical replication of tables.
- 52e4f0cd472d 15.0 landed
-
Move scanint8() to numutils.c
- cfc7191dfea3 15.0 cited
-
Replace Test::More plans with done_testing
- 549ec201d613 15.0 cited
-
Reduce relcache access in WAL sender streaming logical changes
- 6ce16088bfed 15.0 cited
-
Small cleanups related to PUBLICATION framework code
- c9105dd3660f 15.0 cited
-
Add a view to show the stats of subscription workers.
- 8d74fc96db5f 15.0 cited
-
Allow publishing the tables of schema.
- 5a2832465fd8 15.0 cited
-
Doc: improve documentation of CREATE/ALTER SUBSCRIPTION.
- 1882d6cca161 15.0 cited
-
Add PublicationTable and PublicationRelInfo structs
- 0c6828fa987b 15.0 cited
-
Remove unused argument "txn" in maybe_send_schema().
- 93d573d86571 15.0 cited
-
Add prepare API support for streaming transactions in logical replication.
- 63cf61cdeb7b 15.0 cited
-
Unify PostgresNode's new() and get_new_node() methods
- 201a76183e20 15.0 cited
-
Use l*_node() family of functions where appropriate
- 2b00db4fb0c7 15.0 cited
-
Add support for prepared transactions to built-in logical replication.
- a8fd13cab0ba 15.0 cited
-
Restore the portal-level snapshot after procedure COMMIT/ROLLBACK.
- ef9480509622 11.13 cited
-
Rename a parse node to be more general
- 91d1f2d30210 14.0 landed
-
Remove unused column atttypmod from initial tablesync query
- 4ad31bb2ef25 14.0 landed
-
SEARCH and CYCLE clauses
- 3696a600e229 14.0 cited
On Fri, Nov 26, 2021 at 12:40 AM houzj.fnst@fujitsu.com <houzj.fnst@fujitsu.com> wrote: > > When researching and writing a top-up patch about this. > I found a possible issue which I'd like to confirm first. > > It's possible the table is published in two publications A and B, publication A > only publish "insert" , publication B publish "update". When UPDATE, both row > filter in A and B will be executed. Is this behavior expected? > > For example: > ---- Publication > create table tbl1 (a int primary key, b int); > create publication A for table tbl1 where (b<2) with(publish='insert'); > create publication B for table tbl1 where (a>1) with(publish='update'); > > ---- Subscription > create table tbl1 (a int primary key); > CREATE SUBSCRIPTION sub CONNECTION 'dbname=postgres host=localhost > port=10000' PUBLICATION A,B; > > ---- Publication > update tbl1 set a = 2; > > The publication can be created, and when UPDATE, the rowfilter in A (b<2) will > also been executed but the column in it is not part of replica identity. > (I am not against this behavior just confirm) > There seems to be problems related to allowing the row filter to include columns that are not part of the replica identity (in the case of publish=insert). In your example scenario, the tbl1 WHERE clause "(b < 2)" for publication A, that publishes inserts only, causes a problem, because column "b" is not part of the replica identity. To see this, follow the simple example below: (and note, for the Subscription, the provided tbl1 definition has an error, it should also include the 2nd column "b int", same as in the publisher) ---- Publisher: INSERT INTO tbl1 VALUES (1,1); UPDATE tbl1 SET a = 2; Prior to the UPDATE above: On pub side, tbl1 contains (1,1). On sub side, tbl1 contains (1,1) After the above UPDATE: On pub side, tbl1 contains (2,1). On sub side, tbl1 contains (1,1), (2,1) So the UPDATE on the pub side has resulted in an INSERT of (2,1) on the sub side. This is because when (1,1) is UPDATEd to (2,1), it attempts to use the "insert" filter "(b<2)" to determine whether the old value had been inserted (published to subscriber), but finds there is no "b" value (because it only uses RI cols for UPDATE) and so has to assume the old tuple doesn't exist on the subscriber, hence the UPDATE ends up doing an INSERT. INow if the use of RI cols were enforced for the insert filter case, we'd properly know the answer as to whether the old row value had been published and it would have correctly performed an UPDATE instead of an INSERT in this case. Thoughts? Regards, Greg Nancarrow Fujitsu Australia