fix_memory_leak_v2.patch
application/octet-stream
Filename: fix_memory_leak_v2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/replication/pgoutput/pgoutput.c | 28 | 9 |
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index c9c952a278f..58d87a13eb9 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -80,6 +80,7 @@ static void pgoutput_stream_prepare_txn(LogicalDecodingContext *ctx,
ReorderBufferTXN *txn, XLogRecPtr prepare_lsn);
static bool publications_valid;
+static MemoryContext pubctx = NULL;
static List *LoadPublications(List *pubnames);
static void publication_invalidation_cb(Datum arg, int cacheid,
@@ -234,6 +235,7 @@ static bool pgoutput_row_filter(Relation relation, TupleTableSlot *old_slot,
TupleTableSlot **new_slot_ptr,
RelationSyncEntry *entry,
ReorderBufferChangeType *action);
+static void pgoutput_pubctx_reset_callback(void *arg);
/* column list routines */
static void pgoutput_column_list_init(PGOutputData *data,
@@ -420,6 +422,7 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
{
PGOutputData *data = palloc0(sizeof(PGOutputData));
static bool publication_callback_registered = false;
+ MemoryContextCallback *mcallback;
/* Create our memory context for private allocations. */
data->context = AllocSetContextCreate(ctx->context,
@@ -430,6 +433,15 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
"logical replication cache context",
ALLOCSET_DEFAULT_SIZES);
+ Assert(pubctx == NULL);
+ pubctx = AllocSetContextCreate(ctx->context,
+ "logical replication publication list context",
+ ALLOCSET_SMALL_SIZES);
+
+ mcallback = palloc0(sizeof(MemoryContextCallback));
+ mcallback->func = pgoutput_pubctx_reset_callback;
+ MemoryContextRegisterResetCallback(ctx->context, mcallback);
+
ctx->output_plugin_private = data;
/* This plugin uses binary protocol. */
@@ -1696,9 +1708,9 @@ pgoutput_origin_filter(LogicalDecodingContext *ctx,
/*
* Shutdown the output plugin.
*
- * Note, we don't need to clean the data->context and data->cachectx as
- * they are child contexts of the ctx->context so they will be cleaned up by
- * logical decoding machinery.
+ * Note, we don't need to clean the data->context, data->cachectx and pubctx
+ * as they are child contexts of the ctx->context so they will be cleaned up
+ * by logical decoding machinery.
*/
static void
pgoutput_shutdown(LogicalDecodingContext *ctx)
@@ -1708,6 +1720,8 @@ pgoutput_shutdown(LogicalDecodingContext *ctx)
hash_destroy(RelationSyncCache);
RelationSyncCache = NULL;
}
+
+ pubctx = NULL;
}
/*
@@ -2024,12 +2038,11 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
/* Reload publications if needed before use. */
if (!publications_valid)
{
- oldctx = MemoryContextSwitchTo(CacheMemoryContext);
- if (data->publications)
- {
- list_free_deep(data->publications);
- data->publications = NIL;
- }
+ Assert(pubctx);
+
+ MemoryContextReset(pubctx);
+ oldctx = MemoryContextSwitchTo(pubctx);
+
data->publications = LoadPublications(data->publication_names);
MemoryContextSwitchTo(oldctx);
publications_valid = true;
@@ -2402,3 +2415,9 @@ send_repl_origin(LogicalDecodingContext *ctx, RepOriginId origin_id,
}
}
}
+
+static void
+pgoutput_pubctx_reset_callback(void *arg)
+{
+ pubctx = NULL;
+}