v10-0002-Invalidate-Relcaches-while-ALTER-PUBLICATION-REN.patch
application/octet-stream
Filename: v10-0002-Invalidate-Relcaches-while-ALTER-PUBLICATION-REN.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v10-0002
Subject: Invalidate Relcaches while ALTER PUBLICATION RENAME TO
| File | + | − |
|---|---|---|
| src/backend/commands/alter.c | 16 | 0 |
| src/backend/commands/publicationcmds.c | 49 | 0 |
| src/backend/replication/pgoutput/pgoutput.c | 2 | 6 |
| src/include/commands/publicationcmds.h | 2 | 0 |
From f1ecaa5e9c08886f0eab2c038e13d25a195e7d33 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
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