daveg <da...@sonic.net> writes:
> We have installed the patch and have encountered the error as usual.
> However there is no additional output from the patch. I'm speculating
> that the pg_class scan in ScanPgRelationDetailed() fails to return
> tuples somehow.

Evidently not, if it's not logging anything, but now the question is
why.  One possibility is that for some reason RelationGetNumberOfBlocks
is persistently lying about the file size.  (We've seen kernel bugs
before that resulted in transiently wrong values, so this isn't totally
beyond the realm of possibility.)  Please try the attached patch, which
extends the previous one to add a summary line including the number of
blocks physically scanned by the seqscan.

                        regards, tom lane

diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 81cea8b60406dffa7b5d278697ab5ad6cef6a3d8..589513a2d35987b2202ce1162b326db2d358b6fa 100644
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
***************
*** 32,37 ****
--- 32,38 ----
  
  #include "access/genam.h"
  #include "access/reloptions.h"
+ #include "access/relscan.h"
  #include "access/sysattr.h"
  #include "access/transam.h"
  #include "access/xact.h"
***************
*** 64,69 ****
--- 65,71 ----
  #include "optimizer/var.h"
  #include "rewrite/rewriteDefine.h"
  #include "storage/fd.h"
+ #include "storage/bufmgr.h"
  #include "storage/lmgr.h"
  #include "storage/smgr.h"
  #include "utils/array.h"
*************** ScanPgRelation(Oid targetRelId, bool ind
*** 310,315 ****
--- 312,388 ----
  }
  
  /*
+  *		ScanPgRelationDetailed
+  *
+  *		Try to figure out why we failed to locate row for relation.
+  */
+ static HeapTuple
+ ScanPgRelationDetailed(Oid targetRelId)
+ {
+ 	HeapTuple	pg_class_tuple;
+ 	Relation	pg_class_desc;
+ 	SysScanDesc pg_class_scan;
+ 	ScanKeyData key[1];
+ 	int			count = 0;
+ 
+ 	/*
+ 	 * form a scan key
+ 	 */
+ 	ScanKeyInit(&key[0],
+ 				ObjectIdAttributeNumber,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(targetRelId));
+ 
+ 	/*
+ 	 * Open pg_class and fetch tuples, forcing heap scan and disabling
+ 	 * visibility checks.
+ 	 */
+ 	pg_class_desc = heap_open(RelationRelationId, AccessShareLock);
+ 	pg_class_scan = systable_beginscan(pg_class_desc, ClassOidIndexId,
+ 									   false,
+ 									   SnapshotAny,
+ 									   1, key);
+ 
+ 	while (HeapTupleIsValid((pg_class_tuple = systable_getnext(pg_class_scan))))
+ 	{
+ 		Buffer		buf = pg_class_scan->scan->rs_cbuf;
+ 		bool		valid;
+ 
+ 		count++;
+ 
+ 		/* need buffer lock to call HeapTupleSatisfiesVisibility */
+ 		LockBuffer(buf, BUFFER_LOCK_SHARE);
+ 		valid = HeapTupleSatisfiesVisibility(pg_class_tuple,
+ 											 SnapshotNow,
+ 											 buf);
+ 		LockBuffer(buf, BUFFER_LOCK_UNLOCK);
+ 
+ 		elog(LOG, "searching %u for pg_class tuple for index %u: found ctid (%u,%u), xmin %u, xmax %u, flags 0x%4x 0x%4x, valid %d",
+ 			 pg_class_desc->rd_node.relNode,
+ 			 targetRelId,
+ 			 ItemPointerGetBlockNumber(&(pg_class_tuple->t_self)),
+ 			 ItemPointerGetOffsetNumber(&(pg_class_tuple->t_self)),
+ 			 HeapTupleHeaderGetXmin(pg_class_tuple->t_data),
+ 			 HeapTupleHeaderGetXmax(pg_class_tuple->t_data),
+ 			 pg_class_tuple->t_data->t_infomask,
+ 			 pg_class_tuple->t_data->t_infomask2,
+ 			 valid);
+ 	}
+ 
+ 	elog(LOG, "ScanPgRelationDetailed: found %d tuples with OID %u in %u blocks of filenode %u",
+ 		 count,
+ 		 targetRelId,
+ 		 pg_class_scan->scan->rs_nblocks,
+ 		 pg_class_desc->rd_node.relNode);
+ 
+ 	/* all done */
+ 	systable_endscan(pg_class_scan);
+ 	heap_close(pg_class_desc, AccessShareLock);
+ 
+ 	return NULL;
+ }
+ 
+ /*
   *		AllocateRelationDesc
   *
   *		This is used to allocate memory for a new relation descriptor
*************** RelationReloadIndexInfo(Relation relatio
*** 1737,1744 ****
  	indexOK = (RelationGetRelid(relation) != ClassOidIndexId);
  	pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), indexOK);
  	if (!HeapTupleIsValid(pg_class_tuple))
! 		elog(ERROR, "could not find pg_class tuple for index %u",
! 			 RelationGetRelid(relation));
  	relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
  	memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
  	/* Reload reloptions in case they changed */
--- 1810,1824 ----
  	indexOK = (RelationGetRelid(relation) != ClassOidIndexId);
  	pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), indexOK);
  	if (!HeapTupleIsValid(pg_class_tuple))
! 	{
! 		pg_class_tuple = ScanPgRelationDetailed(RelationGetRelid(relation));
! 		if (!HeapTupleIsValid(pg_class_tuple))
! 			elog(ERROR, "could not find pg_class tuple for index %u",
! 				 RelationGetRelid(relation));
! 		else
! 			elog(LOG, "could not find pg_class tuple for index %u, but succeeded on second try",
! 				 RelationGetRelid(relation));
! 	}
  	relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
  	memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
  	/* Reload reloptions in case they changed */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to