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!
This commit is contained in:
parent
98c6e81e94
commit
04103e00f1
9
src/backend/utils/cache/inval.c
vendored
9
src/backend/utils/cache/inval.c
vendored
@ -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,
|
|||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
|
27
src/backend/utils/cache/relcache.c
vendored
27
src/backend/utils/cache/relcache.c
vendored
@ -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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
* 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,
|
|||||||
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)
|
|||||||
* 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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user