From da591c9c967c693fd507d52a79357ca17aa0034a Mon Sep 17 00:00:00 2001 From: "Vigneshwaran C" Date: Mon, 6 Sep 2021 13:37:11 +0800 Subject: [PATCH 1/2] refactor relation cache invalidation code Made the existing relation cache invalidation code into a function. Also made getting the relations based on the publication partition option for a specified relation into a function. This will be used in the later "FOR ALL TABLES IN SCHEMA" implementation patch. --- src/backend/catalog/pg_publication.c | 66 ++++++++++++++++++++-------------- src/backend/commands/publicationcmds.c | 42 +++++++++++----------- src/include/commands/publicationcmds.h | 5 +++ 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 2a2fe03..a587e09 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -136,6 +136,42 @@ pg_relation_is_publishable(PG_FUNCTION_ARGS) PG_RETURN_BOOL(result); } +/* + * Gets the relations based on the publication partition option for a specified + * relation. + */ +static List * +GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt, + Oid relid) +{ + if (get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE && + pub_partopt != PUBLICATION_PART_ROOT) + { + List *all_parts = find_all_inheritors(relid, NoLock, + NULL); + + if (pub_partopt == PUBLICATION_PART_ALL) + result = list_concat(result, all_parts); + else if (pub_partopt == PUBLICATION_PART_LEAF) + { + ListCell *lc; + + foreach(lc, all_parts) + { + Oid partOid = lfirst_oid(lc); + + if (get_rel_relkind(partOid) != RELKIND_PARTITIONED_TABLE) + result = lappend_oid(result, partOid); + } + } + else + Assert(false); + } + else + result = lappend_oid(result, relid); + + return result; +} /* * Insert new publication / relation mapping. @@ -241,7 +277,7 @@ GetRelationPublications(Oid relid) /* * Gets list of relation oids for a publication. * - * This should only be used for normal publications, the FOR ALL TABLES + * This should only be used FOR TABLE publications, the FOR ALL TABLES * should use GetAllTablesPublicationRelations(). */ List * @@ -270,32 +306,8 @@ GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt) Form_pg_publication_rel pubrel; pubrel = (Form_pg_publication_rel) GETSTRUCT(tup); - - if (get_rel_relkind(pubrel->prrelid) == RELKIND_PARTITIONED_TABLE && - pub_partopt != PUBLICATION_PART_ROOT) - { - List *all_parts = find_all_inheritors(pubrel->prrelid, NoLock, - NULL); - - if (pub_partopt == PUBLICATION_PART_ALL) - result = list_concat(result, all_parts); - else if (pub_partopt == PUBLICATION_PART_LEAF) - { - ListCell *lc; - - foreach(lc, all_parts) - { - Oid partOid = lfirst_oid(lc); - - if (get_rel_relkind(partOid) != RELKIND_PARTITIONED_TABLE) - result = lappend_oid(result, partOid); - } - } - else - Assert(false); - } - else - result = lappend_oid(result, pubrel->prrelid); + result = GetPubPartitionOptionRelations(result, pub_partopt, + pubrel->prrelid); } systable_endscan(scan); diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 8487eeb..e1d17f6 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -45,9 +45,6 @@ #include "utils/syscache.h" #include "utils/varlena.h" -/* Same as MAXNUMMESSAGES in sinvaladt.c */ -#define MAX_RELCACHE_INVAL_MSGS 4096 - static List *OpenTableList(List *tables); static void CloseTableList(List *rels); static void PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, @@ -324,23 +321,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, List *relids = GetPublicationRelations(pubform->oid, PUBLICATION_PART_ALL); - /* - * We don't want to send too many individual messages, at some point - * it's cheaper to just reset whole relcache. - */ - if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS) - { - ListCell *lc; - - foreach(lc, relids) - { - Oid relid = lfirst_oid(lc); - - CacheInvalidateRelcacheByRelid(relid); - } - } - else - CacheInvalidateRelcacheAll(); + InvalidatePublicationRels(relids); } ObjectAddressSet(obj, PublicationRelationId, pubform->oid); @@ -351,6 +332,27 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, } /* + * Invalidate the relations. + */ +void +InvalidatePublicationRels(List *relids) +{ + /* + * We don't want to send too many individual messages, at some point it's + * cheaper to just reset whole relcache. + */ + if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS) + { + ListCell *lc; + + foreach(lc, relids) + CacheInvalidateRelcacheByRelid(lfirst_oid(lc)); + } + else + CacheInvalidateRelcacheAll(); +} + +/* * Add or remove table to/from publication. */ static void diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h index a3fa2ac..fa47d6d 100644 --- a/src/include/commands/publicationcmds.h +++ b/src/include/commands/publicationcmds.h @@ -17,6 +17,10 @@ #include "catalog/objectaddress.h" #include "parser/parse_node.h" +#include "utils/inval.h" + +/* Same as MAXNUMMESSAGES in sinvaladt.c */ +#define MAX_RELCACHE_INVAL_MSGS 4096 extern ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt); extern void AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt); @@ -24,5 +28,6 @@ extern void RemovePublicationRelById(Oid proid); extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId); extern void AlterPublicationOwner_oid(Oid pubid, Oid newOwnerId); +extern void InvalidatePublicationRels(List *relids); #endif /* PUBLICATIONCMDS_H */ -- 2.7.2.windows.1