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; +}