Cache lookup failed for relation X [was: DROP FUNCTION cache lookup failed for relation X] - Mailing list pgsql-hackers

From Mark Kirkwood
Subject Cache lookup failed for relation X [was: DROP FUNCTION cache lookup failed for relation X]
Date
Msg-id 47298C0C.50508@paradise.net.nz
Whole thread Raw
In response to Re: DROP FUNCTION failure: cache lookup failed for relation X  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Cache lookup failed for relation X [was: DROP FUNCTION cache lookup failed for relation X]  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Tom Lane wrote:
>
> Still in the think-about-it mode, personally ... my proposed fix is
> certainly much too invasive to consider back-patching, so unless someone
> comes up with a way-simpler idea, it's 8.3 material at best ...
>
>
I ran into a variant of this today - simply creating and dropping a
table repeatedly while doing \d from another session:

Session 1:

perl -e 'while (1) {print "drop table if exists z0; \n create table z0
(a int, b int);\n drop table z0;\n"}' | psql cache > z0.log 2>&1

Session 2:

psql cache
=# \d
ERROR:  cache lookup failed for relation 945897 (in RelationIsVisible,
namespace.c:406)


The previous discussion centered around working on on locking in
dependency.c whilst dropping related objects - but does this apply when
there is just one? Anyway I tried to understand what was happening and
the attached rather hacky patch seems to cure the behaviour -  So I've
submitted it as a discussion aid, rather than 'the way of fixing
this'... since I'm hoping there is a better way :-)

regards

Mark


Index: src/backend/catalog/namespace.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/namespace.c,v
retrieving revision 1.99
diff -c -r1.99 namespace.c
*** src/backend/catalog/namespace.c    27 Aug 2007 03:36:08 -0000    1.99
--- src/backend/catalog/namespace.c    1 Nov 2007 07:55:34 -0000
***************
*** 19,26 ****
--- 19,28 ----
   */
  #include "postgres.h"

+ #include "access/heapam.h"
  #include "access/xact.h"
  #include "catalog/dependency.h"
+ #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_authid.h"
  #include "catalog/pg_conversion.h"
***************
*** 41,46 ****
--- 43,49 ----
  #include "storage/ipc.h"
  #include "utils/acl.h"
  #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
  #include "utils/guc.h"
  #include "utils/inval.h"
  #include "utils/lsyscache.h"
***************
*** 398,409 ****
      Form_pg_class relform;
      Oid            relnamespace;
      bool        visible;

      reltup = SearchSysCache(RELOID,
                              ObjectIdGetDatum(relid),
                              0, 0, 0);
      if (!HeapTupleIsValid(reltup))
!         elog(ERROR, "cache lookup failed for relation %u", relid);
      relform = (Form_pg_class) GETSTRUCT(reltup);

      recomputeNamespacePath();
--- 401,441 ----
      Form_pg_class relform;
      Oid            relnamespace;
      bool        visible;
+     bool        fromcache = true;

      reltup = SearchSysCache(RELOID,
                              ObjectIdGetDatum(relid),
                              0, 0, 0);
      if (!HeapTupleIsValid(reltup))
!     {
!         /* See if we can get it directly. */
!         Relation        relation;
!         HeapScanDesc    scan;
!         ScanKeyData     scanKeyData;
!
!         fromcache = false;
!
!         ScanKeyInit(&scanKeyData,
!                     ObjectIdAttributeNumber,
!                     BTEqualStrategyNumber, F_OIDEQ,
!                     ObjectIdGetDatum(ClassOidIndexId));
!
!         relation = heap_open(RelationRelationId, AccessShareLock);
!
!         scan = heap_beginscan(relation, ActiveSnapshot,
!                               1, &scanKeyData);
!
!         reltup = heap_getnext(scan, ForwardScanDirection);
!         reltup = heap_copytuple(reltup);
!         if (!HeapTupleIsValid(reltup))
!             elog(ERROR, "cache lookup failed for relation %u", relid);
!
!
!         heap_endscan(scan);
!
!         heap_close(relation, AccessShareLock);
!
!     }
      relform = (Form_pg_class) GETSTRUCT(reltup);

      recomputeNamespacePath();
***************
*** 446,452 ****
          }
      }

!     ReleaseSysCache(reltup);

      return visible;
  }
--- 478,487 ----
          }
      }

!     if (fromcache)
!         ReleaseSysCache(reltup);
!     else
!         heap_freetuple(reltup);

      return visible;
  }

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: psql show dbsize?
Next
From: "Gokulakannan Somasundaram"
Date:
Subject: Re: Clarification on a Time travel feature