fix_memory_leak_v1.patch
application/octet-stream
Filename: fix_memory_leak_v1.patch
Type: application/octet-stream
Part: 1
Patch
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/replication/pgoutput/pgoutput.c | 33 | 8 |
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index c9c952a278f..33fe1461e11 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -211,7 +211,7 @@ static HTAB *RelationSyncCache = NULL;
static void init_rel_sync_cache(MemoryContext cachectx);
static void cleanup_rel_sync_cache(TransactionId xid, bool is_commit);
-static RelationSyncEntry *get_rel_sync_entry(PGOutputData *data,
+static RelationSyncEntry *get_rel_sync_entry(LogicalDecodingContext *ctx,
Relation relation);
static void rel_sync_cache_relation_cb(Datum arg, Oid relid);
static void rel_sync_cache_publication_cb(Datum arg, int cacheid,
@@ -234,6 +234,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,
@@ -1426,7 +1427,7 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
if (data->in_streaming)
xid = change->txn->xid;
- relentry = get_rel_sync_entry(data, relation);
+ relentry = get_rel_sync_entry(ctx, relation);
/* First check the table filter */
switch (action)
@@ -1598,7 +1599,7 @@ pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
if (!is_publishable_relation(relation))
continue;
- relentry = get_rel_sync_entry(data, relation);
+ relentry = get_rel_sync_entry(ctx, relation);
if (!relentry->pubactions.pubtruncate)
continue;
@@ -1970,8 +1971,9 @@ set_schema_sent_in_streamed_txn(RelationSyncEntry *entry, TransactionId xid)
* when publishing.
*/
static RelationSyncEntry *
-get_rel_sync_entry(PGOutputData *data, Relation relation)
+get_rel_sync_entry(LogicalDecodingContext *ctx, Relation relation)
{
+ PGOutputData *data = (PGOutputData *) ctx->output_plugin_private;
RelationSyncEntry *entry;
bool found;
MemoryContext oldctx;
@@ -2024,12 +2026,27 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
/* Reload publications if needed before use. */
if (!publications_valid)
{
- oldctx = MemoryContextSwitchTo(CacheMemoryContext);
- if (data->publications)
+ static MemoryContext pubctx = NULL;
+
+ if (pubctx == NULL)
{
- list_free_deep(data->publications);
- data->publications = NIL;
+ MemoryContextCallback *mcallback;
+
+ pubctx = AllocSetContextCreate(ctx->context,
+ "logical replication publication list context",
+ ALLOCSET_SMALL_SIZES);
+
+ mcallback = MemoryContextAllocZero(ctx->context,
+ sizeof(MemoryContextCallback));
+ mcallback->func = pgoutput_pubctx_reset_callback;
+ mcallback->arg = &pubctx;
+ MemoryContextRegisterResetCallback(ctx->context, mcallback);
}
+ else
+ MemoryContextReset(pubctx);
+
+ oldctx = MemoryContextSwitchTo(pubctx);
+
data->publications = LoadPublications(data->publication_names);
MemoryContextSwitchTo(oldctx);
publications_valid = true;
@@ -2402,3 +2419,11 @@ send_repl_origin(LogicalDecodingContext *ctx, RepOriginId origin_id,
}
}
}
+
+static void
+pgoutput_pubctx_reset_callback(void *arg)
+{
+ MemoryContext *pubctx = (MemoryContext *) arg;
+
+ *pubctx = NULL;
+}