From d9c7159903bc9266a0846269c971631f36bb8748 Mon Sep 17 00:00:00 2001
From: Vignesh <vignesh21@gmail.com>
Date: Thu, 12 Dec 2024 19:01:32 +0530
Subject: [PATCH vPG14_] Fix memory leak in pgoutput relation attribute map

The pgoutput module caches relation attribute map and frees it upon
invalidation.  However, this was not getting freed incase of SQL functions like
pg_logical_slot_{get,peek}_changes() which would bloat its cache memory usage.
Every pg_logical_slot_{get,peek}_changes() call for changes on partition table
creates more bloat. To address this issue, a new global static memory context
has been introduced, which is reset during pgoutput_startup to avoid
bloat after each pg_logical_slot_{get,peek}_changes() call.
---
 src/backend/replication/pgoutput/pgoutput.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 78c81888c4..ef2e6ab723 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -64,6 +64,7 @@ static void pgoutput_stream_commit(struct LogicalDecodingContext *ctx,
 
 static bool publications_valid;
 static bool in_streaming;
+static MemoryContext relentrycachectx = NULL;
 
 static List *LoadPublications(List *pubnames);
 static void publication_invalidation_cb(Datum arg, int cacheid,
@@ -345,6 +346,13 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
 		/* Disable the streaming during the slot initialization mode. */
 		ctx->streaming = false;
 	}
+
+	if (relentrycachectx == NULL)
+		relentrycachectx = AllocSetContextCreate(CacheMemoryContext,
+												 "logical replication relation entry cache context",
+												 ALLOCSET_SMALL_SIZES);
+	else
+		MemoryContextReset(relentrycachectx);
 }
 
 /*
@@ -464,7 +472,7 @@ maybe_send_schema(LogicalDecodingContext *ctx,
 		MemoryContext oldctx;
 
 		/* Map must live as long as the session does. */
-		oldctx = MemoryContextSwitchTo(CacheMemoryContext);
+		oldctx = MemoryContextSwitchTo(relentrycachectx);
 
 		/*
 		 * Make copies of the TupleDescs that will live as long as the map
-- 
2.43.0

