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

Reply via email to