From 04103e00f1f0ce12c29954d069e1d4437467f700 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 29 Jan 2000 19:51:59 +0000
Subject: [PATCH] Modify uses of RelationFlushRelation and
 RelationCacheInvalidate so that we *always* rebuild, rather than deleting, an
 invalidated relcache entry that has positive refcount.  Otherwise an SI cache
 overrun leads to dangling Relation pointers all over the place!

---
 src/backend/utils/cache/inval.c    |  9 +++++----
 src/backend/utils/cache/relcache.c | 27 ++++++++++++++++++++++-----
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index ce4230da4f1..473978bd410 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.32 2000/01/26 05:57:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.33 2000/01/29 19:51:59 tgl Exp $
  *
  * Note - this code is real crufty...
  *
@@ -548,15 +548,16 @@ CacheIdInvalidate(Index cacheId,
 /* --------------------------------
  *		ResetSystemCaches
  *
- *		this blows away all tuples in the system catalog caches and
- *		all the cached relation descriptors (and closes the files too).
+ *		This blows away all tuples in the system catalog caches and
+ *		all the cached relation descriptors (and closes their files too).
+ *		Relation descriptors that have positive refcounts are then rebuilt.
  * --------------------------------
  */
 static void
 ResetSystemCaches()
 {
 	ResetSystemCache();
-	RelationCacheInvalidate(false);
+	RelationCacheInvalidate(true);
 }
 
 /* --------------------------------
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index ea11b026884..4a6c86d84d9 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.87 2000/01/26 05:57:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.88 2000/01/29 19:51:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1406,7 +1406,18 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
 	 */
 	if (PointerIsValid(relation) && !relation->rd_myxactonly)
 	{
-
+#if 1
+		/*
+		 * Seems safest just to NEVER flush rels with positive refcounts.
+		 * I think the code only had that proviso as a rather lame method of
+		 * cleaning up unused relcache entries that had dangling refcounts
+		 * (following elog(ERROR) with an open rel).  Now we rely on
+		 * RelationCacheAbort to clean up dangling refcounts, so there's no
+		 * good reason to ever risk flushing a rel with positive refcount.
+		 * IMHO anyway --- tgl 1/29/00.
+		 */
+		RelationFlushRelation(&relation, true);
+#else
 		/*
 		 * The boolean onlyFlushReferenceCountZero in RelationFlushReln()
 		 * should be set to true when we are incrementing the command
@@ -1414,6 +1425,7 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
 		 * can be determined by checking the current xaction status.
 		 */
 		RelationFlushRelation(&relation, CurrentXactInProgress());
+#endif
 	}
 }
 
@@ -1436,7 +1448,7 @@ RelationFlushIndexes(Relation *r,
 	if (relation->rd_rel->relkind == RELKIND_INDEX &&	/* XXX style */
 		(!OidIsValid(accessMethodId) ||
 		 relation->rd_rel->relam == accessMethodId))
-		RelationFlushRelation(&relation, false);
+		RelationFlushRelation(&relation, true);
 }
 
 #endif
@@ -1469,9 +1481,14 @@ RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId)
  *	 Will blow away either all the cached relation descriptors or
  *	 those that have a zero reference count.
  *
+ *	 CAUTION: this is only called with onlyFlushReferenceCountZero=true
+ *	 at present, so that relation descriptors with positive refcounts
+ *	 are rebuilt rather than clobbered.  It would only be safe to use a
+ *	 "false" parameter in a totally idle backend with no open relations.
+ *
  *	 This is currently used only to recover from SI message buffer overflow,
- *	 so onlyFlushReferenceCountZero is always false.  We do not blow away
- *	 transaction-local relations, since they cannot be targets of SI updates.
+ *	 so we do not blow away transaction-local relations; they cannot be
+ *	 targets of SI updates.
  */
 void
 RelationCacheInvalidate(bool onlyFlushReferenceCountZero)
-- 
GitLab