From 76ccf73f2bd3c8af621c24fd3ebddcc2ff21d807 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 21 Nov 1999 01:58:22 +0000 Subject: [PATCH] Repair problem exposed by Jan's new parallel-regression-test scaffold: inval.c thought it could safely use the catcache to look up the OIDs of system relations. Not good, considering that inval.c could be called during catcache loading, if a shared-inval message arrives. Rip out the lookup logic and instead use the known OIDs from pg_class.h. --- src/backend/utils/cache/catcache.c | 16 +--- src/backend/utils/cache/inval.c | 132 ++++++++++------------------- src/backend/utils/cache/relcache.c | 26 ++---- src/backend/utils/init/postinit.c | 8 +- src/include/utils/inval.h | 24 +----- src/include/utils/relcache.h | 4 +- 6 files changed, 61 insertions(+), 149 deletions(-) diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 423a5d7286..e5a1684041 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.52 1999/11/19 18:51:48 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.53 1999/11/21 01:58:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -819,7 +819,7 @@ InitSysCache(char *relname, * -------------------------------- */ static HeapTuple -SearchSelfReferences(const struct catcache * cache) +SearchSelfReferences(struct catcache * cache) { HeapTuple ntp; Relation rel; @@ -983,23 +983,11 @@ SearchSysCache(struct catcache * cache, * ---------------- */ - /* ---------- - * It is definitely insufficient. While modifying the regression - * test to run independent tests concurrently it happened, that - * this code fails VERY often. ISTM that 'cache' points into - * shared memory, but that 'busy' means this backend is loading - * a new entry. So when another backend has set busy, this one - * think's it detected a recursion. - * - * Need's a smarter detection mechanism - Jan - * if (cache->busy) { elog(ERROR, "SearchSysCache: recursive use of cache %d", cache->id); } cache->busy = true; - * ---------- - */ /* ---------------- * open the relation associated with the cache diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 26f45a1e9b..d89a1f678a 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.29 1999/11/17 23:51:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.30 1999/11/21 01:58:22 tgl Exp $ * * Note - this code is real crufty... * @@ -18,23 +18,36 @@ #include "catalog/catalog.h" #include "catalog/catname.h" #include "catalog/heap.h" +#include "catalog/pg_class.h" #include "miscadmin.h" #include "storage/sinval.h" #include "utils/catcache.h" #include "utils/inval.h" #include "utils/relcache.h" -static InvalidationEntry InvalidationEntryAllocate(uint16 size); -static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function) ()); -static LocalInvalid LocalInvalidRegister(LocalInvalid invalid, - InvalidationEntry entry); -static void getmyrelids(void); - /* ---------------- * private invalidation structures * ---------------- */ + +typedef struct InvalidationUserData +{ + struct InvalidationUserData *dataP[1]; /* VARIABLE LENGTH */ +} InvalidationUserData; /* VARIABLE LENGTH STRUCTURE */ + +typedef struct InvalidationEntryData +{ + InvalidationUserData *nextP; + InvalidationUserData userData; /* VARIABLE LENGTH ARRAY */ +} InvalidationEntryData; /* VARIABLE LENGTH STRUCTURE */ + +typedef Pointer InvalidationEntry; + +typedef InvalidationEntry LocalInvalid; + +#define EmptyLocalInvalid NULL + typedef struct CatalogInvalidationData { Index cacheId; @@ -66,15 +79,14 @@ typedef InvalidationMessageData *InvalidationMessage; * variables and macros * ---------------- */ -static LocalInvalid Invalid = EmptyLocalInvalid; /* XXX global */ +static LocalInvalid Invalid = EmptyLocalInvalid; /* head of linked list */ -Oid MyRelationRelationId = InvalidOid; -Oid MyAttributeRelationId = InvalidOid; -Oid MyAMRelationId = InvalidOid; -Oid MyAMOPRelationId = InvalidOid; -#define ValidateHacks() \ - if (!OidIsValid(MyRelationRelationId)) getmyrelids() +static InvalidationEntry InvalidationEntryAllocate(uint16 size); +static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function) ()); +static LocalInvalid LocalInvalidRegister(LocalInvalid invalid, + InvalidationEntry entry); + /* ---------------------------------------------------------------- * "local" invalidation support functions @@ -99,7 +111,8 @@ InvalidationEntryAllocate(uint16 size) /* -------------------------------- * LocalInvalidRegister - * Returns a new local cache invalidation state containing a new entry. + * Link an invalidation entry into a chain of them. Really ugly + * coding here. * -------------------------------- */ static LocalInvalid @@ -117,7 +130,7 @@ LocalInvalidRegister(LocalInvalid invalid, /* -------------------------------- * LocalInvalidInvalidate * Processes, then frees all entries in a local cache - * invalidation state. + * invalidation list. * -------------------------------- */ static void @@ -187,7 +200,7 @@ CacheIdRegisterLocalInvalid(Index cacheId, ItemPointerCopy(pointer, &message->any.catalog.pointerData); /* ---------------- - * Note: Invalid is a global variable + * Add message to linked list of unprocessed messages. * ---------------- */ Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry) message); @@ -224,32 +237,12 @@ RelationIdRegisterLocalInvalid(Oid relationId, Oid objectId) message->any.relation.objectId = objectId; /* ---------------- - * Note: Invalid is a global variable + * Add message to linked list of unprocessed messages. * ---------------- */ Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry) message); } -/* -------------------------------- - * getmyrelids - * -------------------------------- - */ -static void -getmyrelids() -{ - MyRelationRelationId = RelnameFindRelid(RelationRelationName); - Assert(RelationRelationName != InvalidOid); - - MyAttributeRelationId = RelnameFindRelid(AttributeRelationName); - Assert(AttributeRelationName != InvalidOid); - - MyAMRelationId = RelnameFindRelid(AccessMethodRelationName); - Assert(MyAMRelationId != InvalidOid); - - MyAMOPRelationId = RelnameFindRelid(AccessMethodOperatorRelationName); - Assert(MyAMOPRelationId != InvalidOid); -} - /* -------------------------------- * CacheIdInvalidate * @@ -284,38 +277,23 @@ CacheIdInvalidate(Index cacheId, CacheIdInvalidate_DEBUG1; - ValidateHacks(); /* XXX */ - /* ---------------- - * if the cacheId is the oid of any of the tuples in the - * following system relations, then assume we are invalidating - * a relation descriptor + * if the cacheId is the oid of any of the following system relations, + * then assume we are invalidating a relation descriptor * ---------------- */ - if (cacheId == MyRelationRelationId) + if (cacheId == RelOid_pg_class) { RelationIdInvalidateRelationCacheByRelationId(hashIndex); return; } - if (cacheId == MyAttributeRelationId) + if (cacheId == RelOid_pg_attribute) { RelationIdInvalidateRelationCacheByRelationId(hashIndex); return; } - if (cacheId == MyAMRelationId) - { - RelationIdInvalidateRelationCacheByAccessMethodId(hashIndex); - return; - } - - if (cacheId == MyAMOPRelationId) - { - RelationIdInvalidateRelationCacheByAccessMethodId(InvalidOid); - return; - } - /* ---------------- * Yow! the caller asked us to invalidate something else. * ---------------- @@ -446,29 +424,22 @@ RelationInvalidateRelationCache(Relation relation, void (*function) ()) { Oid relationId; - Oid objectId = (Oid) 0; + Oid objectId; /* ---------------- * get the relation object id * ---------------- */ - ValidateHacks(); /* XXX */ relationId = RelationGetRelid(relation); /* ---------------- - * + * is it one of the ones we need to send an SI message for? * ---------------- */ - if (relationId == MyRelationRelationId) + if (relationId == RelOid_pg_class) objectId = tuple->t_data->t_oid; - else if (relationId == MyAttributeRelationId) + else if (relationId == RelOid_pg_attribute) objectId = ((Form_pg_attribute) GETSTRUCT(tuple))->attrelid; - else if (relationId == MyAMRelationId) - objectId = tuple->t_data->t_oid; - else if (relationId == MyAMOPRelationId) - { - ; /* objectId is unused */ - } else return; @@ -482,19 +453,6 @@ RelationInvalidateRelationCache(Relation relation, } -/* - * InitLocalInvalidateData - * - * Setup this before anything could ever get invalid! - * Called by InitPostgres(); - */ -void -InitLocalInvalidateData() -{ - ValidateHacks(); -} - - /* * DiscardInvalid * Causes the invalidated cache state to be discarded. @@ -528,6 +486,8 @@ DiscardInvalid() void RegisterInvalid(bool send) { + LocalInvalid invalid; + /* ---------------- * debugging stuff * ---------------- @@ -537,17 +497,19 @@ RegisterInvalid(bool send) #endif /* defined(INVALIDDEBUG) */ /* ---------------- - * Note: Invalid is a global variable + * Process and free the current list of inval messages. * ---------------- */ + invalid = Invalid; + Invalid = EmptyLocalInvalid; /* anything added now is part of a new list */ + if (send) - LocalInvalidInvalidate(Invalid, + LocalInvalidInvalidate(invalid, InvalidationMessageRegisterSharedInvalid); else - LocalInvalidInvalidate(Invalid, + LocalInvalidInvalidate(invalid, InvalidationMessageCacheInvalidate); - Invalid = EmptyLocalInvalid; } /* diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index d6d2ee4b4e..b668474411 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.79 1999/11/18 13:56:28 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.80 1999/11/21 01:58:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -209,11 +209,6 @@ do { \ static void formrdesc(char *relationName, u_int natts, FormData_pg_attribute *att); -#ifdef NOT_USED /* See comments at line 1304 */ -static void RelationFlushIndexes(Relation *r, Oid accessMethodId); - -#endif - static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo); static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo); static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo); @@ -1431,12 +1426,9 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId) } } -#if NOT_USED /* See comments at line 1304 */ -/* -------------------------------- - * RelationIdInvalidateRelationCacheByAccessMethodId - * - * RelationFlushIndexes is needed for use with HashTableWalk.. - * -------------------------------- +#if NOT_USED +/* only used by RelationIdInvalidateRelationCacheByAccessMethodId, + * which is dead code. */ static void RelationFlushIndexes(Relation *r, @@ -1459,11 +1451,10 @@ RelationFlushIndexes(Relation *r, #endif +#if NOT_USED void RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId) { -#ifdef NOT_USED - /* * 25 aug 1992: mao commented out the ht walk below. it should be * doing the right thing, in theory, but flushing reldescs for index @@ -1471,14 +1462,15 @@ RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId) * don't want to introduce new bugs. this code never executed before, * so i'm turning it off for now. after the release is cut, i'll fix * this up. + * + * 20 nov 1999: this code has still never done anything, so I'm + * cutting the routine out of the system entirely. tgl */ HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushIndexes, accessMethodId); -#else - return; -#endif } +#endif /* * RelationCacheInvalidate diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 72c87f1619..c5b3f06b8c 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.52 1999/10/25 03:07:51 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.53 1999/11/21 01:58:21 tgl Exp $ * * NOTES * InitPostgres() is the function called from PostgresMain @@ -553,12 +553,6 @@ InitPostgres(char *name) /* database name */ */ InitUserid(); - /* - * Initialize local data in cache invalidation stuff - */ - if (!bootstrap) - InitLocalInvalidateData(); - if (lockingOff) LockDisable(true); diff --git a/src/include/utils/inval.h b/src/include/utils/inval.h index f63941f396..a559c4374d 100644 --- a/src/include/utils/inval.h +++ b/src/include/utils/inval.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: inval.h,v 1.13 1999/07/15 23:04:22 momjian Exp $ + * $Id: inval.h,v 1.14 1999/11/21 01:58:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -15,32 +15,10 @@ #include "access/htup.h" -extern void InitLocalInvalidateData(void); - extern void DiscardInvalid(void); extern void RegisterInvalid(bool send); extern void RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple); -/* - * POSTGRES local cache invalidation definitions. (originates from linval.h) - */ -typedef struct InvalidationUserData -{ - struct InvalidationUserData *dataP[1]; /* VARIABLE LENGTH */ -} InvalidationUserData; /* VARIABLE LENGTH STRUCTURE */ - -typedef struct InvalidationEntryData -{ - InvalidationUserData *nextP; - InvalidationUserData userData; /* VARIABLE LENGTH ARRAY */ -} InvalidationEntryData; /* VARIABLE LENGTH STRUCTURE */ - -typedef Pointer InvalidationEntry; - -typedef InvalidationEntry LocalInvalid; - -#define EmptyLocalInvalid NULL - #endif /* INVAL_H */ diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 95fab3b22a..2aeec820df 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: relcache.h,v 1.15 1999/10/03 23:55:38 tgl Exp $ + * $Id: relcache.h,v 1.16 1999/11/21 01:58:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,8 +32,6 @@ extern void RelationRebuildRelation(Relation relation); extern void RelationIdInvalidateRelationCacheByRelationId(Oid relationId); -extern void RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId); - extern void RelationCacheInvalidate(bool onlyFlushReferenceCountZero); extern void RelationRegisterRelation(Relation relation); -- 2.40.0