diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 64f62de635f..f3acc64c451 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -232,6 +232,7 @@ static bool get_schema_sent_in_streamed_txn(RelationSyncEntry *entry, TransactionId xid); static void init_tuple_slot(PGOutputData *data, Relation relation, RelationSyncEntry *entry); +static void pgoutput_memory_context_reset(void *arg); /* row filter routines */ static EState *create_estate_for_relation(Relation rel); @@ -393,11 +394,18 @@ parse_output_parameters(List *options, PGOutputData *data) } /* - * Callback of PGOutputData->context in charge of cleaning pubctx. + * Memory context reset callback of PGOutputData->context. */ static void -pgoutput_pubctx_reset_callback(void *arg) +pgoutput_memory_context_reset(void *arg) { + if (RelationSyncCache) + { + hash_destroy(RelationSyncCache); + RelationSyncCache = NULL; + } + + /* Better safe than sorry */ pubctx = NULL; } @@ -426,8 +434,12 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, "logical replication publication list context", ALLOCSET_SMALL_SIZES); + /* + * Ensure to cleanup RelationSyncCache even when logical decoding invoked + * via SQL interface ends up with an error. + */ mcallback = palloc0(sizeof(MemoryContextCallback)); - mcallback->func = pgoutput_pubctx_reset_callback; + mcallback->func = pgoutput_memory_context_reset; MemoryContextRegisterResetCallback(ctx->context, mcallback); ctx->output_plugin_private = data; @@ -1761,14 +1773,7 @@ pgoutput_origin_filter(LogicalDecodingContext *ctx, static void pgoutput_shutdown(LogicalDecodingContext *ctx) { - if (RelationSyncCache) - { - hash_destroy(RelationSyncCache); - RelationSyncCache = NULL; - } - - /* Better safe than sorry */ - pubctx = NULL; + pgoutput_memory_context_reset(NULL); } /*