From f1ecaa5e9c08886f0eab2c038e13d25a195e7d33 Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Mon, 3 Mar 2025 19:41:04 +0900 Subject: [PATCH v10 2/2] Invalidate Relcaches while ALTER PUBLICATION RENAME TO --- src/backend/commands/alter.c | 16 +++++++ src/backend/commands/publicationcmds.c | 49 +++++++++++++++++++++ src/backend/replication/pgoutput/pgoutput.c | 8 +--- src/include/commands/publicationcmds.h | 2 + 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 78c1d4e1b8..2187d55a2e 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -338,6 +338,22 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name) InvokeObjectPostAlterHook(classId, objectId, 0); + /* Do post catalog-update tasks */ + if (classId == PublicationRelationId) + { + Form_pg_publication pub = (Form_pg_publication) GETSTRUCT(oldtup); + + /* + * Invalidate relsynccaches. + * + * Unlike ALTER PUBLICATION ADD/SET/DROP commands, renaming a + * publication does not impact the publication status of tables. + * Therefore, we do not need to invalidate relcache to rebuild the + * rd_pubdesc. Instead, we invalidate only the relsyncache. + */ + InvalidatePubRelSyncCaches(pub->oid, pub->puballtables); + } + /* Release memory */ pfree(values); pfree(nulls); diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 150a768d16..2ae0f807f2 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -491,6 +491,43 @@ pub_contains_invalid_column(Oid pubid, Relation relation, List *ancestors, return *invalid_column_list || *invalid_gen_col; } +/* + * Invalidate entries in the RelationSyncCache for relations included in the + * specified publication, either via FOR TABLE or FOR TABLES IN SCHEMA. + * + * If 'puballtables' is true, invalidate all cache entries. + */ +void +InvalidatePubRelSyncCaches(Oid pubid, bool puballtables) +{ + if (puballtables) + { + CacheInvalidateRelSyncAll(); + } + else + { + List *relids = NIL; + List *schemarelids = NIL; + + /* + * For partitioned tables, we must invalidate all partitions and + * itself. WAL records for INSERT/UPDATE/DELETE specify leaf + * tables as a target. However, WAL records for TRUNCATE specify + * both a root and its leaves. + */ + relids = GetPublicationRelations(pubid, + PUBLICATION_PART_ALL); + schemarelids = GetAllSchemaPublicationRelations(pubid, + PUBLICATION_PART_ALL); + + relids = list_concat_unique_oid(relids, schemarelids); + + InvalidateRelSyncCaches(relids); + } + + return; +} + /* check_functions_in_node callback */ static bool contain_mutable_or_user_functions_checker(Oid func_id, void *context) @@ -2096,3 +2133,15 @@ defGetGeneratedColsOption(DefElem *def) return PUBLISH_GENCOLS_NONE; /* keep compiler quiet */ } + +/* + * Invalidate the relsyncaches. + */ +void +InvalidateRelSyncCaches(List *relids) +{ + ListCell *lc; + + foreach(lc, relids) + CacheInvalidateRelSync(lfirst_oid(lc)); +} diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 9063af6e1d..ed806c5430 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -531,6 +531,8 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, CacheRegisterSyscacheCallback(PUBLICATIONOID, publication_invalidation_cb, (Datum) 0); + CacheRegisterRelSyncCallback(rel_sync_cache_relation_cb, + (Datum) 0); publication_callback_registered = true; } @@ -1789,12 +1791,6 @@ static void publication_invalidation_cb(Datum arg, int cacheid, uint32 hashvalue) { publications_valid = false; - - /* - * Also invalidate per-relation cache so that next time the filtering info - * is checked it will be updated with the new publication settings. - */ - rel_sync_cache_publication_cb(arg, cacheid, hashvalue); } /* diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h index e11a942ea0..8eb1795d47 100644 --- a/src/include/commands/publicationcmds.h +++ b/src/include/commands/publicationcmds.h @@ -38,5 +38,7 @@ extern bool pub_contains_invalid_column(Oid pubid, Relation relation, char pubgencols_type, bool *invalid_column_list, bool *invalid_gen_col); +extern void InvalidatePubRelSyncCaches(Oid pubid, bool puballtables); +extern void InvalidateRelSyncCaches(List *relids); #endif /* PUBLICATIONCMDS_H */ -- 2.43.5