On Mon, Mar 10, 2025 at 6:42 PM Hayato Kuroda (Fujitsu)
<kuroda.hay...@fujitsu.com> wrote:
>
> > Currently, only the leaf partition is invalidated when the published table 
> > is
> > partitioned. However, I think pgoutput could cache both the partitioned 
> > table
> > and the leaf partition table as relsync entries.
> >
> > For INSERT/UPDATE/DELETE on a partitioned table, only the leaf partition's
> > relsync entry is used in pgoutput, but the TRUNCATE references the parent
> > table's relsync entry.
>
> I think your analysis is correct. PSA new version. Below part contains my 
> analysis.
>

I have made several cosmetic changes atop 0001 patch in the attached.
Additionally, fixed an issue in AddRelsyncInvalidationMessage() to
consider invalidating all the RelSyncCache entries. Kindly include
these in the next version if you find the changes are okay.

-- 
With Regards,
Amit Kapila.
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 35df9be5e54..a0c49519977 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -497,7 +497,9 @@ AddRelcacheInvalidationMessage(InvalidationMsgsGroup *group,
 /*
  * Add a relsync inval entry
  *
- * We put these into the relcache subgroup for simplicity.
+ * We put these into the relcache subgroup for simplicity. This message is the
+ * same as AddRelcacheInvalidationMessage() except that it is for
+ * RelationSyncCache maintained by decoding plugin pgoutput.
  */
 static void
 AddRelsyncInvalidationMessage(InvalidationMsgsGroup *group,
@@ -505,11 +507,11 @@ AddRelsyncInvalidationMessage(InvalidationMsgsGroup 
*group,
 {
        SharedInvalidationMessage msg;
 
-       /* Don't add a duplicate item */
-       /* We assume dbId need not be checked because it will never change */
+       /* Don't add a duplicate item. */
        ProcessMessageSubGroup(group, RelCacheMsgs,
                                                   if (msg->rc.id == 
SHAREDINVALRELSYNC_ID &&
-                                                          msg->rc.relId == 
relId)
+                                                          (msg->rc.relId == 
relId ||
+                                                               msg->rc.relId 
== InvalidOid))
                                                   return);
 
        /* OK, add the item */
@@ -650,9 +652,9 @@ RegisterRelcacheInvalidation(InvalidationInfo *info, Oid 
dbId, Oid relId)
 }
 
 /*
- * RegisterRelcacheInvalidation
+ * RegisterRelsyncInvalidation
  *
- * As above, but register a relsync invalidation event.
+ * As above, but register a relsynccache invalidation event.
  */
 static void
 RegisterRelsyncInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
@@ -660,7 +662,6 @@ RegisterRelsyncInvalidation(InvalidationInfo *info, Oid 
dbId, Oid relId)
        AddRelsyncInvalidationMessage(&info->CurrentCmdInvalidMsgs, dbId, 
relId);
 }
 
-
 /*
  * RegisterSnapshotInvalidation
  *
@@ -1684,9 +1685,8 @@ CacheInvalidateRelcacheByRelid(Oid relid)
        ReleaseSysCache(tup);
 }
 
-
 /*
- * RelationCacheInvalidate
+ * CacheInvalidateRelSync
  *             Register invalidation of the cache in logical decoding output 
plugin
  *             for a database.
  *
@@ -1701,7 +1701,6 @@ CacheInvalidateRelSync(Oid relid)
                                                                MyDatabaseId, 
relid);
 }
 
-
 /*
  * CacheInvalidateRelSyncAll
  *             Register invalidation of the whole cache in logical decoding 
output
@@ -1713,7 +1712,6 @@ CacheInvalidateRelSyncAll(void)
        CacheInvalidateRelSync(InvalidOid);
 }
 
-
 /*
  * CacheInvalidateSmgr
  *             Register invalidation of smgr references to a physical relation.
@@ -1858,7 +1856,7 @@ CacheRegisterRelcacheCallback(RelcacheCallbackFunction 
func,
 /*
  * CacheRegisterRelSyncCallback
  *             Register the specified function to be called for all future
- *             decoding-cache invalidation events.
+ *             decoding plugin's relation cache invalidation events.
  *
  * This function is intended to be call from the logical decoding output
  * plugins.
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index 90a5af4ed8f..f168b5fbf8c 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.h
@@ -27,7 +27,7 @@
  *     * invalidate an smgr cache entry for a specific physical relation
  *     * invalidate the mapped-relation mapping for a given database
  *     * invalidate any saved snapshot that might be used to scan a given 
relation
- *     * invalidate a specific entry for specific output plugin
+ *     * invalidate a RelationSyncCache entry for a specific relation
  * More types could be added if needed.  The message type is identified by
  * the first "int8" field of the message struct.  Zero or positive means a
  * specific-catcache inval message (and also serves as the catcache ID field).
@@ -47,12 +47,12 @@
  * catcache inval messages must be generated for each of its caches, since
  * the hash keys will generally be different.
  *
- * Catcache, relcache, and snapshot invalidations are transactional, and so
- * are sent to other backends upon commit.  Internally to the generating
- * backend, they are also processed at CommandCounterIncrement so that later
- * commands in the same transaction see the new state.  The generating backend
- * also has to process them at abort, to flush out any cache state it's loaded
- * from no-longer-valid entries.
+ * Catcache, relcache, relsynccache, and snapshot invalidations are
+ * transactional, and so are sent to other backends upon commit.  Internally
+ * to the generating backend, they are also processed at
+ * CommandCounterIncrement so that later commands in the same transaction see
+ * the new state.  The generating backend also has to process them at abort,
+ * to flush out any cache state it's loaded from no-longer-valid entries.
  *
  * smgr and relation mapping invalidations are non-transactional: they are
  * sent immediately when the underlying file change is made.
@@ -117,7 +117,7 @@ typedef struct
 {
        int8            id;                             /* type field --- must 
be first */
        Oid                     dbId;                   /* database ID */
-       Oid                     relid;                  /* relation ID, or 0 if 
whole relcache */
+       Oid                     relid;                  /* relation ID, or 0 if 
whole RelationSyncCache */
 } SharedInvalRelSyncMsg;
 
 typedef union

Reply via email to