aboutsummaryrefslogtreecommitdiff
path: root/src/backend/replication/logical/relation.c
diff options
context:
space:
mode:
authorAmit Kapila <akapila@postgresql.org>2022-06-15 10:16:35 +0530
committerAmit Kapila <akapila@postgresql.org>2022-06-15 10:16:35 +0530
commit16f5a8da76f21576987790df828082cb7bb1bdad (patch)
treeeab3a5738328bf1267d044698ee32e1df3e7334f /src/backend/replication/logical/relation.c
parent12b8fb34a933456ca762c98bc2047e608b7a1079 (diff)
downloadpostgresql-16f5a8da76f21576987790df828082cb7bb1bdad.tar.gz
postgresql-16f5a8da76f21576987790df828082cb7bb1bdad.zip
Fix cache look-up failures while applying changes in logical replication.
While building a new attrmap which maps partition attribute numbers to remoterel's, we incorrectly update the map for dropped column attributes. Later, it caused cache look-up failure when we tried to use the map to fetch the information about attributes. This also fixes the partition map cache invalidation which was using the wrong type cast to fetch the entry. We were using stale partition map entry after invalidation which leads to the assertion or cache look-up failure. Reported-by: Shi Yu Author: Hou Zhijie, Shi Yu Reviewed-by: Amit Langote, Amit Kapila Backpatch-through: 13, where it was introduced Discussion: https://postgr.es/m/OSZPR01MB6310F46CD425A967E4AEF736FDA49@OSZPR01MB6310.jpnprd01.prod.outlook.com
Diffstat (limited to 'src/backend/replication/logical/relation.c')
-rw-r--r--src/backend/replication/logical/relation.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index 901bff99745..283afa5d9d7 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -418,7 +418,7 @@ logicalrep_rel_close(LogicalRepRelMapEntry *rel, LOCKMODE lockmode)
static void
logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid)
{
- LogicalRepRelMapEntry *entry;
+ LogicalRepPartMapEntry *entry;
/* Just to be sure. */
if (LogicalRepPartMap == NULL)
@@ -431,11 +431,11 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid)
hash_seq_init(&status, LogicalRepPartMap);
/* TODO, use inverse lookup hashtable? */
- while ((entry = (LogicalRepRelMapEntry *) hash_seq_search(&status)) != NULL)
+ while ((entry = (LogicalRepPartMapEntry *) hash_seq_search(&status)) != NULL)
{
- if (entry->localreloid == reloid)
+ if (entry->relmapentry.localreloid == reloid)
{
- entry->localrelvalid = false;
+ entry->relmapentry.localrelvalid = false;
hash_seq_term(&status);
break;
}
@@ -448,8 +448,8 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid)
hash_seq_init(&status, LogicalRepPartMap);
- while ((entry = (LogicalRepRelMapEntry *) hash_seq_search(&status)) != NULL)
- entry->localrelvalid = false;
+ while ((entry = (LogicalRepPartMapEntry *) hash_seq_search(&status)) != NULL)
+ entry->relmapentry.localrelvalid = false;
}
}
@@ -502,7 +502,6 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
Oid partOid = RelationGetRelid(partrel);
AttrMap *attrmap = root->attrmap;
bool found;
- int i;
MemoryContext oldctx;
if (LogicalRepPartMap == NULL)
@@ -513,31 +512,40 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
(void *) &partOid,
HASH_ENTER, &found);
- if (found)
- return &part_entry->relmapentry;
+ entry = &part_entry->relmapentry;
- memset(part_entry, 0, sizeof(LogicalRepPartMapEntry));
+ if (found && entry->localrelvalid)
+ return entry;
/* Switch to longer-lived context. */
oldctx = MemoryContextSwitchTo(LogicalRepPartMapContext);
- part_entry->partoid = partOid;
+ if (!found)
+ {
+ memset(part_entry, 0, sizeof(LogicalRepPartMapEntry));
+ part_entry->partoid = partOid;
+ }
- /* Remote relation is copied as-is from the root entry. */
- entry = &part_entry->relmapentry;
- entry->remoterel.remoteid = remoterel->remoteid;
- entry->remoterel.nspname = pstrdup(remoterel->nspname);
- entry->remoterel.relname = pstrdup(remoterel->relname);
- entry->remoterel.natts = remoterel->natts;
- entry->remoterel.attnames = palloc(remoterel->natts * sizeof(char *));
- entry->remoterel.atttyps = palloc(remoterel->natts * sizeof(Oid));
- for (i = 0; i < remoterel->natts; i++)
+ if (!entry->remoterel.remoteid)
{
- entry->remoterel.attnames[i] = pstrdup(remoterel->attnames[i]);
- entry->remoterel.atttyps[i] = remoterel->atttyps[i];
+ int i;
+
+ /* Remote relation is copied as-is from the root entry. */
+ entry = &part_entry->relmapentry;
+ entry->remoterel.remoteid = remoterel->remoteid;
+ entry->remoterel.nspname = pstrdup(remoterel->nspname);
+ entry->remoterel.relname = pstrdup(remoterel->relname);
+ entry->remoterel.natts = remoterel->natts;
+ entry->remoterel.attnames = palloc(remoterel->natts * sizeof(char *));
+ entry->remoterel.atttyps = palloc(remoterel->natts * sizeof(Oid));
+ for (i = 0; i < remoterel->natts; i++)
+ {
+ entry->remoterel.attnames[i] = pstrdup(remoterel->attnames[i]);
+ entry->remoterel.atttyps[i] = remoterel->atttyps[i];
+ }
+ entry->remoterel.replident = remoterel->replident;
+ entry->remoterel.attkeys = bms_copy(remoterel->attkeys);
}
- entry->remoterel.replident = remoterel->replident;
- entry->remoterel.attkeys = bms_copy(remoterel->attkeys);
entry->localrel = partrel;
entry->localreloid = partOid;
@@ -562,7 +570,11 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
{
AttrNumber root_attno = map->attnums[attno];
- entry->attrmap->attnums[attno] = attrmap->attnums[root_attno - 1];
+ /* 0 means it's a dropped attribute. See comments atop AttrMap. */
+ if (root_attno == 0)
+ entry->attrmap->attnums[attno] = -1;
+ else
+ entry->attrmap->attnums[attno] = attrmap->attnums[root_attno - 1];
}
}
else