From 3ffa79dbf27aec61fb9d7ac348a19e42a307d06d Mon Sep 17 00:00:00 2001
From: "houzj.fnst" <houzj.fnst@cn.fujitsu.com>
Date: Mon, 13 Jun 2022 14:42:55 +0800
Subject: [PATCH] Fix memory leak about attrmap

When rebuilding the relcache mapping on subscriber, we didn't release the
no longer useful attribute mapping's memory which would result in memory
leak. Fix it by releasing the no longer useful mapping's memory when
rebuilding.

Since attribute mappings was refactored on PG13~HEAD, we should use
free_attrmap instead of pfree to release its memory on these branches. Fix
one place where we still use pfree to release the mapping memory.

Author: Hou Zhijie
Reviewed-by: Amit Langote, Amit Kapila, Shi yu
Backpatch-through: 10, where it was introduced
Discussion: https://postgr.es/m/OSZPR01MB6310F46CD425A967E4AEF736FDA49@OSZPR01MB6310.jpnprd01.prod.outlook.com
---
 src/backend/replication/logical/relation.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index 5f511701d9..7346208388 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -144,7 +144,7 @@ logicalrep_relmap_free_entry(LogicalRepRelMapEntry *entry)
 	bms_free(remoterel->attkeys);
 
 	if (entry->attrmap)
-		pfree(entry->attrmap);
+		free_attrmap(entry->attrmap);
 }
 
 /*
@@ -373,6 +373,13 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
 		int			i;
 		Bitmapset  *missingatts;
 
+		/* Release the no-longer-useful attrmap, if any. */
+		if (entry->attrmap)
+		{
+			free_attrmap(entry->attrmap);
+			entry->attrmap = NULL;
+		}
+
 		/* Try to find and lock the relation by name. */
 		relid = RangeVarGetRelid(makeRangeVar(remoterel->nspname,
 											  remoterel->relname, -1),
@@ -608,6 +615,13 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
 		part_entry->partoid = partOid;
 	}
 
+	/* Release the no-longer-useful attrmap, if any. */
+	if (entry->attrmap)
+	{
+		free_attrmap(entry->attrmap);
+		entry->attrmap = NULL;
+	}
+
 	if (!entry->remoterel.remoteid)
 	{
 		int			i;
-- 
2.18.4

