From e72ce3656c043e0c1d99373833da04f508429691 Mon Sep 17 00:00:00 2001 From: Shi Yu Date: Tue, 21 Feb 2023 10:55:46 +0800 Subject: [PATCH v2] Avoid duplicate registration of callbacks in pgoutput --- src/backend/replication/pgoutput/pgoutput.c | 58 +++++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 98377c094b..20c740f7fb 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -82,6 +82,7 @@ static void pgoutput_stream_prepare_txn(LogicalDecodingContext *ctx, static bool publications_valid; static bool in_streaming; static bool publish_no_origin; +static bool callback_registered = false; static List *LoadPublications(List *pubnames); static void publication_invalidation_cb(Datum arg, int cacheid, @@ -504,12 +505,15 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, /* Init publication state. */ data->publications = NIL; publications_valid = false; - CacheRegisterSyscacheCallback(PUBLICATIONOID, - publication_invalidation_cb, - (Datum) 0); + /* Register callbacks if we didn't do that. */ + if (!callback_registered) + CacheRegisterSyscacheCallback(PUBLICATIONOID, + publication_invalidation_cb, + (Datum) 0); /* Initialize relation schema cache. */ init_rel_sync_cache(CacheMemoryContext); + callback_registered = true; } else { @@ -1946,28 +1950,36 @@ init_rel_sync_cache(MemoryContext cachectx) Assert(RelationSyncCache != NULL); - /* We must update the cache entry for a relation after a relcache flush */ - CacheRegisterRelcacheCallback(rel_sync_cache_relation_cb, (Datum) 0); - /* - * Flush all cache entries after a pg_namespace change, in case it was a - * schema rename affecting a relation being replicated. - */ - CacheRegisterSyscacheCallback(NAMESPACEOID, - rel_sync_cache_publication_cb, - (Datum) 0); + /* Register callbacks if we didn't do that. */ + if (!callback_registered) + { + /* + * We must update the cache entry for a relation after a relcache + * flush + */ + CacheRegisterRelcacheCallback(rel_sync_cache_relation_cb, (Datum) 0); - /* - * Flush all cache entries after any publication changes. (We need no - * callback entry for pg_publication, because publication_invalidation_cb - * will take care of it.) - */ - CacheRegisterSyscacheCallback(PUBLICATIONRELMAP, - rel_sync_cache_publication_cb, - (Datum) 0); - CacheRegisterSyscacheCallback(PUBLICATIONNAMESPACEMAP, - rel_sync_cache_publication_cb, - (Datum) 0); + /* + * Flush all cache entries after a pg_namespace change, in case it was + * a schema rename affecting a relation being replicated. + */ + CacheRegisterSyscacheCallback(NAMESPACEOID, + rel_sync_cache_publication_cb, + (Datum) 0); + + /* + * Flush all cache entries after any publication changes. (We need no + * callback entry for pg_publication, because + * publication_invalidation_cb will take care of it.) + */ + CacheRegisterSyscacheCallback(PUBLICATIONRELMAP, + rel_sync_cache_publication_cb, + (Datum) 0); + CacheRegisterSyscacheCallback(PUBLICATIONNAMESPACEMAP, + rel_sync_cache_publication_cb, + (Datum) 0); + } } /* -- 2.31.1