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;
}
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster