log_missing_indexes-2.patch
text/x-patch
Filename: log_missing_indexes-2.patch
Type: text/x-patch
Part: 0
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 */