Commit 04103e00 authored by Tom Lane's avatar Tom Lane

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!
parent 98c6e81e
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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... * Note - this code is real crufty...
* *
...@@ -548,15 +548,16 @@ CacheIdInvalidate(Index cacheId, ...@@ -548,15 +548,16 @@ CacheIdInvalidate(Index cacheId,
/* -------------------------------- /* --------------------------------
* ResetSystemCaches * ResetSystemCaches
* *
* this blows away all tuples in the system catalog caches and * This blows away all tuples in the system catalog caches and
* all the cached relation descriptors (and closes the files too). * all the cached relation descriptors (and closes their files too).
* Relation descriptors that have positive refcounts are then rebuilt.
* -------------------------------- * --------------------------------
*/ */
static void static void
ResetSystemCaches() ResetSystemCaches()
{ {
ResetSystemCache(); ResetSystemCache();
RelationCacheInvalidate(false); RelationCacheInvalidate(true);
} }
/* -------------------------------- /* --------------------------------
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -1406,7 +1406,18 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
*/ */
if (PointerIsValid(relation) && !relation->rd_myxactonly) 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() * The boolean onlyFlushReferenceCountZero in RelationFlushReln()
* should be set to true when we are incrementing the command * should be set to true when we are incrementing the command
...@@ -1414,6 +1425,7 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId) ...@@ -1414,6 +1425,7 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
* can be determined by checking the current xaction status. * can be determined by checking the current xaction status.
*/ */
RelationFlushRelation(&relation, CurrentXactInProgress()); RelationFlushRelation(&relation, CurrentXactInProgress());
#endif
} }
} }
...@@ -1436,7 +1448,7 @@ RelationFlushIndexes(Relation *r, ...@@ -1436,7 +1448,7 @@ RelationFlushIndexes(Relation *r,
if (relation->rd_rel->relkind == RELKIND_INDEX && /* XXX style */ if (relation->rd_rel->relkind == RELKIND_INDEX && /* XXX style */
(!OidIsValid(accessMethodId) || (!OidIsValid(accessMethodId) ||
relation->rd_rel->relam == accessMethodId)) relation->rd_rel->relam == accessMethodId))
RelationFlushRelation(&relation, false); RelationFlushRelation(&relation, true);
} }
#endif #endif
...@@ -1469,9 +1481,14 @@ RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId) ...@@ -1469,9 +1481,14 @@ RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId)
* Will blow away either all the cached relation descriptors or * Will blow away either all the cached relation descriptors or
* those that have a zero reference count. * 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, * This is currently used only to recover from SI message buffer overflow,
* so onlyFlushReferenceCountZero is always false. We do not blow away * so we do not blow away transaction-local relations; they cannot be
* transaction-local relations, since they cannot be targets of SI updates. * targets of SI updates.
*/ */
void void
RelationCacheInvalidate(bool onlyFlushReferenceCountZero) RelationCacheInvalidate(bool onlyFlushReferenceCountZero)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment