]> granicus.if.org Git - postgresql/commitdiff
Repair problem exposed by Jan's new parallel-regression-test scaffold:
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 21 Nov 1999 01:58:22 +0000 (01:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 21 Nov 1999 01:58:22 +0000 (01:58 +0000)
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
src/backend/utils/cache/inval.c
src/backend/utils/cache/relcache.c
src/backend/utils/init/postinit.c
src/include/utils/inval.h
src/include/utils/relcache.h

index 423a5d728616ce90c958e01e236b09dc8b874ad5..e5a1684041c709f7b343a7fa68b47879f4a50fe5 100644 (file)
@@ -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
index 26f45a1e9b2d0ede5eb7293b78eaf1dc2d524518..d89a1f678a48afcfea20b6ca5769f16736ce4fb6 100644 (file)
@@ -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...
  *
 #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;
 }
 
 /*
index d6d2ee4b4e9e001e2f8188a113aa19f4219f3dbc..b66847441190ea95881a34b029a7ba292c6ff594 100644 (file)
@@ -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
index 72c87f161964f141f4277fa5fd5f4b9e63fd1158..c5b3f06b8cbbc49186604a4b894ff9eceec333af 100644 (file)
@@ -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);
 
index f63941f39672ec00629d8c3df1a0b7000e72a3bf..a559c4374dc0be63515bc2d946c700e535cd2698 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 
 #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 */
index 95fab3b22aeb89f7f358f0d48327389a700c27ba..2aeec820dff9c42ab1e2d25b3c6b96a6870319a4 100644 (file)
@@ -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);