This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit e3e0003329f060e688e74e8c0de68e6c40e56b29
Author: Amit Kapila <[email protected]>
AuthorDate: Thu Jun 16 08:32:10 2022 +0530

    Fix data inconsistency between publisher and subscriber.
    
    We were not updating the partition map cache in the subscriber even when
    the corresponding remote rel is changed. Due to this data was getting
    incorrectly replicated for partition tables after the publisher has
    changed the table schema.
    
    Fix it by resetting the required entries in the partition map cache after
    receiving a new relation mapping from the publisher.
    
    Reported-by: Shi Yu
    Author: Shi Yu, Hou Zhijie
    Reviewed-by: Amit Langote, Amit Kapila
    Backpatch-through: 13, where it was introduced
    Discussion: 
https://postgr.es/m/oszpr01mb6310f46cd425a967e4aef736fd...@oszpr01mb6310.jpnprd01.prod.outlook.com
---
 src/backend/replication/logical/relation.c | 34 ++++++++++++++++++++++++++++++
 src/backend/replication/logical/worker.c   |  3 +++
 src/include/replication/logicalrelation.h  |  1 +
 src/test/subscription/t/013_partition.pl   | 17 ++++++++++++++-
 4 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/backend/replication/logical/relation.c 
b/src/backend/replication/logical/relation.c
index fad8c92b2ef..a9fa26fe686 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -493,6 +493,40 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid)
        }
 }
 
+/*
+ * Reset the entries in the partition map that refer to remoterel.
+ *
+ * Called when new relation mapping is sent by the publisher to update our
+ * expected view of incoming data from said publisher.
+ *
+ * Note that we don't update the remoterel information in the entry here,
+ * we will update the information in logicalrep_partition_open to avoid
+ * unnecessary work.
+ */
+void
+logicalrep_partmap_reset_relmap(LogicalRepRelation *remoterel)
+{
+       HASH_SEQ_STATUS status;
+       LogicalRepPartMapEntry *part_entry;
+       LogicalRepRelMapEntry *entry;
+
+       if (LogicalRepPartMap == NULL)
+               return;
+
+       hash_seq_init(&status, LogicalRepPartMap);
+       while ((part_entry = (LogicalRepPartMapEntry *) 
hash_seq_search(&status)) != NULL)
+       {
+               entry = &part_entry->relmapentry;
+
+               if (entry->remoterel.remoteid != remoterel->remoteid)
+                       continue;
+
+               logicalrep_relmap_free_entry(entry);
+
+               memset(entry, 0, sizeof(LogicalRepRelMapEntry));
+       }
+}
+
 /*
  * Initialize the partition map cache.
  */
diff --git a/src/backend/replication/logical/worker.c 
b/src/backend/replication/logical/worker.c
index adcbc36ecef..5335e5f5c62 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -1191,6 +1191,9 @@ apply_handle_relation(StringInfo s)
 
        rel = logicalrep_read_rel(s);
        logicalrep_relmap_update(rel);
+
+       /* Also reset all entries in the partition map that refer to remoterel. 
*/
+       logicalrep_partmap_reset_relmap(rel);
 }
 
 /*
diff --git a/src/include/replication/logicalrelation.h 
b/src/include/replication/logicalrelation.h
index 3c662d3abcf..10f91490b5c 100644
--- a/src/include/replication/logicalrelation.h
+++ b/src/include/replication/logicalrelation.h
@@ -38,6 +38,7 @@ typedef struct LogicalRepRelMapEntry
 } LogicalRepRelMapEntry;
 
 extern void logicalrep_relmap_update(LogicalRepRelation *remoterel);
+extern void logicalrep_partmap_reset_relmap(LogicalRepRelation *remoterel);
 
 extern LogicalRepRelMapEntry *logicalrep_rel_open(LogicalRepRelId remoteid,
                                                                                
                  LOCKMODE lockmode);
diff --git a/src/test/subscription/t/013_partition.pl 
b/src/test/subscription/t/013_partition.pl
index e53bc5b568f..568e4d104e0 100644
--- a/src/test/subscription/t/013_partition.pl
+++ b/src/test/subscription/t/013_partition.pl
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 69;
+use Test::More tests => 70;
 
 # setup
 
@@ -841,3 +841,18 @@ $node_publisher->wait_for_catchup('sub2');
 $result = $node_subscriber2->safe_psql('postgres',
        "SELECT a, b, c FROM tab5 ORDER BY 1");
 is($result, qq(3|1|), 'updates of tab5 replicated correctly after altering 
table on subscriber');
+
+# Test that replication into the partitioned target table continues to
+# work correctly when the published table is altered.
+$node_publisher->safe_psql(
+       'postgres', q{
+       ALTER TABLE tab5 DROP COLUMN b, ADD COLUMN c INT;
+       ALTER TABLE tab5 ADD COLUMN b INT;});
+
+$node_publisher->safe_psql('postgres', "UPDATE tab5 SET c = 1 WHERE a = 3");
+
+$node_publisher->wait_for_catchup('sub2');
+
+$result = $node_subscriber2->safe_psql('postgres',
+       "SELECT a, b, c FROM tab5 ORDER BY 1");
+is($result, qq(3||1), 'updates of tab5 replicated correctly after altering 
table on publisher');


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to