From e8cb14d97feac9d4575ded49b976e7b7a54db794 Mon Sep 17 00:00:00 2001 From: tanghy Date: Wed, 10 Nov 2021 13:46:43 +0800 Subject: [PATCH] Invalidate relcache when setting REPLICA IDENTITY Author: Haiying Tang, Hou Zhijie Reviewed-by: Hou Zhijie --- src/backend/commands/tablecmds.c | 1 + src/test/subscription/t/001_rep_changes.pl | 51 +++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 857cc5ce6e..b77112bd3a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15488,6 +15488,7 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid, CatalogTupleUpdate(pg_index, &pg_index_tuple->t_self, pg_index_tuple); InvokeObjectPostAlterHookArg(IndexRelationId, thisIndexOid, 0, InvalidOid, is_internal); + CacheInvalidateRelcache(rel); } heap_freetuple(pg_index_tuple); } diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl index 9531d81f19..0be579b509 100644 --- a/src/test/subscription/t/001_rep_changes.pl +++ b/src/test/subscription/t/001_rep_changes.pl @@ -6,7 +6,7 @@ use strict; use warnings; use PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils; -use Test::More tests => 32; +use Test::More tests => 34; # Initialize publisher node my $node_publisher = PostgreSQL::Test::Cluster->new('publisher'); @@ -57,6 +57,22 @@ $node_publisher->safe_psql('postgres', "CREATE INDEX idx_no_replidentity_index ON tab_no_replidentity_index(c1)" ); +# Replicate the changes with replica identity index but not primary key +$node_publisher->safe_psql('postgres', + "CREATE TABLE tab_replidentity_index(a int not null, b int not null)"); +$node_publisher->safe_psql('postgres', + "CREATE UNIQUE INDEX idx_replidentity_index_a ON tab_replidentity_index(a)" +); +$node_publisher->safe_psql('postgres', + "CREATE UNIQUE INDEX idx_replidentity_index_b ON tab_replidentity_index(b)" +); +# using index idx_replidentity_index_a +$node_publisher->safe_psql('postgres', + "ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_a;" +); +$node_publisher->safe_psql('postgres', + "INSERT INTO tab_replidentity_index VALUES(1, 1)"); + # Setup structure on subscriber $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)"); $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_ins (a int)"); @@ -87,13 +103,20 @@ $node_subscriber->safe_psql('postgres', "CREATE INDEX idx_no_replidentity_index ON tab_no_replidentity_index(c1)" ); +# replication of the table without replica identity index but not primary key +$node_subscriber->safe_psql('postgres', + "CREATE TABLE tab_replidentity_index(a int not null, b int not null)"); +$node_subscriber->safe_psql('postgres', + "CREATE UNIQUE INDEX idx_replidentity_index_b ON tab_replidentity_index(b)" +); + # Setup logical replication my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub"); $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)"); $node_publisher->safe_psql('postgres', - "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include, tab_nothing, tab_full_pk, tab_no_replidentity_index" + "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include, tab_nothing, tab_full_pk, tab_no_replidentity_index, tab_replidentity_index" ); $node_publisher->safe_psql('postgres', "ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins"); @@ -325,6 +348,30 @@ is( $result, qq(1|bar 2|baz), 'update works with REPLICA IDENTITY FULL and a primary key'); +# check replication with REPLICA IDENTITY but not primary key +# using index idx_replidentity_index_b +$node_subscriber->safe_psql('postgres', +); + +$result = $node_subscriber->safe_psql('postgres', + "SELECT * FROM tab_replidentity_index"), +is( $result, qq(1|1), + "check initial data on subscriber"); + +# using idx_replidentity_index_b and update +$node_subscriber->safe_psql('postgres', qq[ + ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_b; +]); +$node_publisher->safe_psql('postgres', qq[ + ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_b; + UPDATE tab_replidentity_index SET a = -a; +]); +$node_publisher->wait_for_catchup('tap_sub'); +$result = $node_subscriber->safe_psql('postgres', + "SELECT * FROM tab_replidentity_index"), +is( $result, qq(-1|1), + "update works with REPLICA IDENTITY"); + # Check that subscriber handles cases where update/delete target tuple # is missing. We have to look for the DEBUG1 log messages about that, # so temporarily bump up the log verbosity. -- 2.18.4