Commit 0980adfd authored by Amit Kapila's avatar Amit Kapila

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/OSZPR01MB6310F46CD425A967E4AEF736FDA49@OSZPR01MB6310.jpnprd01.prod.outlook.com
parent d457cb4e
...@@ -486,6 +486,40 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid) ...@@ -486,6 +486,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. * Initialize the partition map cache.
*/ */
......
...@@ -1191,6 +1191,9 @@ apply_handle_relation(StringInfo s) ...@@ -1191,6 +1191,9 @@ apply_handle_relation(StringInfo s)
rel = logicalrep_read_rel(s); rel = logicalrep_read_rel(s);
logicalrep_relmap_update(rel); logicalrep_relmap_update(rel);
/* Also reset all entries in the partition map that refer to remoterel. */
logicalrep_partmap_reset_relmap(rel);
} }
/* /*
......
...@@ -38,6 +38,7 @@ typedef struct LogicalRepRelMapEntry ...@@ -38,6 +38,7 @@ typedef struct LogicalRepRelMapEntry
} LogicalRepRelMapEntry; } LogicalRepRelMapEntry;
extern void logicalrep_relmap_update(LogicalRepRelation *remoterel); extern void logicalrep_relmap_update(LogicalRepRelation *remoterel);
extern void logicalrep_partmap_reset_relmap(LogicalRepRelation *remoterel);
extern LogicalRepRelMapEntry *logicalrep_rel_open(LogicalRepRelId remoteid, extern LogicalRepRelMapEntry *logicalrep_rel_open(LogicalRepRelId remoteid,
LOCKMODE lockmode); LOCKMODE lockmode);
......
...@@ -6,7 +6,7 @@ use strict; ...@@ -6,7 +6,7 @@ use strict;
use warnings; use warnings;
use PostgresNode; use PostgresNode;
use TestLib; use TestLib;
use Test::More tests => 69; use Test::More tests => 70;
# setup # setup
...@@ -841,3 +841,18 @@ $node_publisher->wait_for_catchup('sub2'); ...@@ -841,3 +841,18 @@ $node_publisher->wait_for_catchup('sub2');
$result = $node_subscriber2->safe_psql('postgres', $result = $node_subscriber2->safe_psql('postgres',
"SELECT a, b, c FROM tab5 ORDER BY 1"); "SELECT a, b, c FROM tab5 ORDER BY 1");
is($result, qq(3|1|), 'updates of tab5 replicated correctly after altering table on subscriber'); 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');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment