log_missing_indexes-2.patch

text/x-patch

Filename: log_missing_indexes-2.patch
Type: text/x-patch
Part: 0
Message: Re: error: could not find pg_class tuple for index 2662
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 */