public inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v7 2/3] Remove "dead" flag from catcache tuple
44+ messages / 2 participants
[nested] [flat]

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v5 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 1ebcc7dcd3..3e6c4720dc 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 81587c3fe6..36940f4e3b 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.18.4


----Next_Part(Thu_Nov_19_14_25_36_2020_063)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v5-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v7 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Wed_Jan_27_10_13_08_2021_482)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v7-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* [PATCH v6 2/3] Remove "dead" flag from catcache tuple
@ 2020-11-18 07:57  Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Kyotaro Horiguchi @ 2020-11-18 07:57 UTC (permalink / raw)

---
 src/backend/utils/cache/catcache.c | 43 +++++++++++++-----------------
 src/include/utils/catcache.h       | 10 -------
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 644d92dd9a..611b65168d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -480,6 +480,13 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 	Assert(ct->refcount == 0);
 	Assert(ct->my_cache == cache);
 
+	/* delink from linked list if not yet */
+	if (ct->cache_elem.prev)
+	{
+		dlist_delete(&ct->cache_elem);
+		ct->cache_elem.prev = NULL;
+	}
+
 	if (ct->c_list)
 	{
 		/*
@@ -487,14 +494,10 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
 		 * which will recurse back to me, and the recursive call will do the
 		 * work.  Set the "dead" flag to make sure it does recurse.
 		 */
-		ct->dead = true;
 		CatCacheRemoveCList(cache, ct->c_list);
 		return;					/* nothing left to do */
 	}
 
-	/* delink from linked list */
-	dlist_delete(&ct->cache_elem);
-
 	/*
 	 * Free keys when we're dealing with a negative entry, normal entries just
 	 * point into tuple, allocated together with the CatCTup.
@@ -534,7 +537,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
 		/* if the member is dead and now has no references, remove it */
 		if (
 #ifndef CATCACHE_FORCE_RELEASE
-			ct->dead &&
+			ct->cache_elem.prev == NULL &&
 #endif
 			ct->refcount == 0)
 			CatCacheRemoveCTup(cache, ct);
@@ -609,7 +612,9 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
+
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -688,7 +693,8 @@ ResetCatalogCache(CatCache *cache)
 			if (ct->refcount > 0 ||
 				(ct->c_list && ct->c_list->refcount > 0))
 			{
-				ct->dead = true;
+				dlist_delete(&ct->cache_elem);
+				ct->cache_elem.prev = NULL;
 				/* list, if any, was marked dead above */
 				Assert(ct->c_list == NULL || ct->c_list->dead);
 			}
@@ -1268,9 +1274,6 @@ SearchCatCacheInternal(CatCache *cache,
 	{
 		ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-		if (ct->dead)
-			continue;			/* ignore dead entries */
-
 		if (ct->hash_value != hashValue)
 			continue;			/* quickly skip entry if wrong hash val */
 
@@ -1522,7 +1525,6 @@ ReleaseCatCache(HeapTuple tuple)
 								  offsetof(CatCTup, tuple));
 
 	/* Safety checks to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
 	Assert(ct->refcount > 0);
 
 	ct->refcount--;
@@ -1530,7 +1532,7 @@ ReleaseCatCache(HeapTuple tuple)
 
 	if (
 #ifndef CATCACHE_FORCE_RELEASE
-		ct->dead &&
+		ct->cache_elem.prev == NULL &&
 #endif
 		ct->refcount == 0 &&
 		(ct->c_list == NULL || ct->c_list->refcount == 0))
@@ -1737,8 +1739,8 @@ SearchCatCacheList(CatCache *cache,
 			{
 				ct = dlist_container(CatCTup, cache_elem, iter.cur);
 
-				if (ct->dead || ct->negative)
-					continue;	/* ignore dead and negative entries */
+				if (ct->negative)
+					continue;	/* ignore negative entries */
 
 				if (ct->hash_value != hashValue)
 					continue;	/* quickly skip entry if wrong hash val */
@@ -1799,14 +1801,13 @@ SearchCatCacheList(CatCache *cache,
 	{
 		foreach(ctlist_item, ctlist)
 		{
+			Assert (ct->cache_elem.prev != NULL);
+
 			ct = (CatCTup *) lfirst(ctlist_item);
 			Assert(ct->c_list == NULL);
 			Assert(ct->refcount > 0);
 			ct->refcount--;
 			if (
-#ifndef CATCACHE_FORCE_RELEASE
-				ct->dead &&
-#endif
 				ct->refcount == 0 &&
 				(ct->c_list == NULL || ct->c_list->refcount == 0))
 				CatCacheRemoveCTup(cache, ct);
@@ -1834,9 +1835,6 @@ SearchCatCacheList(CatCache *cache,
 		/* release the temporary refcount on the member */
 		Assert(ct->refcount > 0);
 		ct->refcount--;
-		/* mark list dead if any members already dead */
-		if (ct->dead)
-			cl->dead = true;
 	}
 	Assert(i == nmembers);
 
@@ -1960,11 +1958,9 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	 * Finish initializing the CatCTup header, and add it to the cache's
 	 * linked list and counts.
 	 */
-	ct->ct_magic = CT_MAGIC;
 	ct->my_cache = cache;
 	ct->c_list = NULL;
 	ct->refcount = 0;			/* for the moment */
-	ct->dead = false;
 	ct->negative = negative;
 	ct->hash_value = hashValue;
 	ct->lastaccess = catcacheclock;
@@ -2158,9 +2154,6 @@ PrintCatCacheLeakWarning(HeapTuple tuple)
 	CatCTup    *ct = (CatCTup *) (((char *) tuple) -
 								  offsetof(CatCTup, tuple));
 
-	/* Safety check to ensure we were handed a cache entry */
-	Assert(ct->ct_magic == CT_MAGIC);
-
 	elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
 		 ct->my_cache->cc_relname, ct->my_cache->id,
 		 ItemPointerGetBlockNumber(&(tuple->t_self)),
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 291e857e38..53b0bf31eb 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -87,9 +87,6 @@ typedef struct catcache
 
 typedef struct catctup
 {
-	int			ct_magic;		/* for identifying CatCTup entries */
-#define CT_MAGIC   0x57261502
-
 	uint32		hash_value;		/* hash value for this tuple's keys */
 
 	/*
@@ -106,19 +103,12 @@ typedef struct catctup
 	dlist_node	cache_elem;		/* list member of per-bucket list */
 
 	/*
-	 * A tuple marked "dead" must not be returned by subsequent searches.
-	 * However, it won't be physically deleted from the cache until its
-	 * refcount goes to zero.  (If it's a member of a CatCList, the list's
-	 * refcount must go to zero, too; also, remember to mark the list dead at
-	 * the same time the tuple is marked.)
-	 *
 	 * A negative cache entry is an assertion that there is no tuple matching
 	 * a particular key.  This is just as useful as a normal entry so far as
 	 * avoiding catalog searches is concerned.  Management of positive and
 	 * negative entries is identical.
 	 */
 	int			refcount;		/* number of active references */
-	bool		dead;			/* dead but not yet removed? */
 	bool		negative;		/* negative cache entry? */
 	HeapTupleData tuple;		/* tuple management header */
 	uint64		lastaccess;		/* timestamp in us of the last usage */
-- 
2.27.0


----Next_Part(Thu_Jan_14_17_32_27_2021_995)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="v6-0003-catcachebench.patch"



^ permalink  raw  reply  [nested|flat] 44+ messages in thread

* Is the XLP_BKP_REMOVABLE flag itself removable/obsolete?
@ 2026-02-26 14:53  Matthias van de Meent <[email protected]>
  0 siblings, 0 replies; 44+ messages in thread

From: Matthias van de Meent @ 2026-02-26 14:53 UTC (permalink / raw)
  To: PostgreSQL Hackers <[email protected]>; +Cc: Noah Misch <[email protected]>; Michael Paquier <[email protected]>

Whilst going through WAL definitions and headers, I noticed
XLP_BKP_REMOVABLE, which doesn't have any users in the PG repo. It is
still being written into WAL page headers, but never accessed or acted
on, and has been present since before the big WAL record revamp in
2014 (2c03216d83).

Is this flag actually useful and used in the more recent versions of
PostgreSQL? If not, let's remove it.

Even back in 2011 (when XLP_BKP_REMOVABLE was introduced in its
current form) there were questions about the practical uses of this
flag [0].
Back then, the pg_lesslog tool (iiuc, a tool for archiving WAL, with
deep WAL introspection/reparsing for reduced storage needs) was the
only mention of a tool that uses it, but 15 years later I'm not sure
there are any tools left which use that flag - pg_lesslog seems to
have had its last release in 2010, and seems to have died a quiet
death.

In 2025, Noah sent a mail to -hackers [1] showing a race condition
that could get this flag to be set on incorrect WAL pages, which could
cause issues for software that relied on this flag's indicated value.

Finally, I (and Michael in 2018 [2]) also couldn't find any code in
any of release branches >= 9.2 that used this flag, I couldn't find
any user in Debian Code Search, nor did I find any code on Github that
would indicate any real usage of that flag: There are some WAL
decoding tools that display its presence on the page, or which copy
the definition into their respective project in their language of
choice, but never any that have material logic that utilizes whatever
this flag means for more than displaying the WAL page state.

/cc Noah Misch and Michael Paquier, you both suggested at some point
to remove the flag.


Kind regards,

Matthias van de Meent
Databricks (https://www.databricks.com)

[0] https://postgr.es/m/flat/18626.1323703037%40sss.pgh.pa.us
[1] https://postgr.es/m/[email protected]
[2] https://postgr.es/m/20180330235757.GA1394%40paquier.xyz


Attachments:

  [application/octet-stream] v1-0001-Remove-XLP_BKP_REMOVABLE.patch (3.4K, ../../CAEze2WhiwKSoAvfUggjDeoeY0-rz9cTpfrHcqvBMmJxv-K_5DA@mail.gmail.com/2-v1-0001-Remove-XLP_BKP_REMOVABLE.patch)
  download | inline diff:
From e7f6ce3bc5f3415fd9630b53009b33d1257ab9df Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <[email protected]>
Date: Thu, 26 Feb 2026 15:42:36 +0100
Subject: [PATCH v1] Remove XLP_BKP_REMOVABLE

There are no known users of this flag (the last supposed user was
lesslog), and there was a known race condition making the reliance
on this flag impractical.
---
 src/backend/access/transam/xlog.c  | 22 ----------------------
 src/include/access/xlog_internal.h |  5 ++---
 2 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 13cce9b49f1..2ee1abb80fa 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2114,22 +2114,6 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
 
 		/* NewPage->xlp_rem_len = 0; */	/* done by memset */
 
-		/*
-		 * If online backup is not in progress, mark the header to indicate
-		 * that WAL records beginning in this page have removable backup
-		 * blocks.  This allows the WAL archiver to know whether it is safe to
-		 * compress archived WAL data by transforming full-block records into
-		 * the non-full-block format.  It is sufficient to record this at the
-		 * page level because we force a page switch (in fact a segment
-		 * switch) when starting a backup, so the flag will be off before any
-		 * records can be written during the backup.  At the end of a backup,
-		 * the last page will be marked as all unsafe when perhaps only part
-		 * is unsafe, but at worst the archiver would miss the opportunity to
-		 * compress a few records.
-		 */
-		if (Insert->runningBackups == 0)
-			NewPage->xlp_info |= XLP_BKP_REMOVABLE;
-
 		/*
 		 * If first page of an XLOG segment file, make it a long header.
 		 */
@@ -9037,12 +9021,6 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
 		 * pg_wal directory was not included in the base backup and the WAL
 		 * archive was cleared too before starting the backup.
 		 *
-		 * This also ensures that we have emitted a WAL page header that has
-		 * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
-		 * Therefore, if a WAL archiver (such as pglesslog) is trying to
-		 * compress out removable backup blocks, it won't remove any that
-		 * occur after this point.
-		 *
 		 * During recovery, we skip forcing XLOG file switch, which means that
 		 * the backup taken during recovery is not available for the special
 		 * recovery case described above.
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index fbc5d77ab39..62e4310e92d 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -74,12 +74,11 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
 #define XLP_FIRST_IS_CONTRECORD		0x0001
 /* This flag indicates a "long" page header */
 #define XLP_LONG_HEADER				0x0002
-/* This flag indicates backup blocks starting in this page are optional */
-#define XLP_BKP_REMOVABLE			0x0004
+/* 0x0004 is unused */
 /* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */
 #define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008
 /* All defined flag bits in xlp_info (used for validity checking of header) */
-#define XLP_ALL_FLAGS				0x000F
+#define XLP_ALL_FLAGS				0x000B
 
 #define XLogPageHeaderSize(hdr)		\
 	(((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)
-- 
2.50.1 (Apple Git-155)



^ permalink  raw  reply  [nested|flat] 44+ messages in thread


end of thread, other threads:[~2026-02-26 14:53 UTC | newest]

Thread overview: 44+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v5 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v6 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2020-11-18 07:57 [PATCH v7 2/3] Remove "dead" flag from catcache tuple Kyotaro Horiguchi <[email protected]>
2026-02-26 14:53 Is the XLP_BKP_REMOVABLE flag itself removable/obsolete? Matthias van de Meent <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox