提交 0ff952e7 编写于 作者: A Ashwin Agrawal

Validate pg_class pg_type tuple after index fetch.

While fetching the pg_class or pg_type tuple using index, perform sanity
check to make sure tuple intended to read, is the tuple index is
pointing too. This is just sanity check to make sure index is not broken
and not returning some incorrect tuple to contain the damage.
上级 c8a21e0d
......@@ -998,6 +998,54 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
return true;
}
/*
* This function performs checks for certain system tables to validate tuple
* fetched from table has the key, using which it was fetched from index.
*/
static void
CrossCheckTuple(int cacheId,
Datum key1,
Datum key2,
Datum key3,
Datum key4,
HeapTuple tuple)
{
Form_pg_class rd_rel;
switch (cacheId)
{
case RELOID:
if (HeapTupleGetOid(tuple) != DatumGetObjectId(key1))
{
elog(ERROR, "pg_class_oid_index is broken, oid=%d is pointing to tuple with oid=%d (xmin:%u xmax:%u)",
DatumGetObjectId(key1), HeapTupleGetOid(tuple),
HeapTupleHeaderGetXmin((tuple)->t_data),
HeapTupleHeaderGetXmax((tuple)->t_data));
}
break;
case RELNAMENSP:
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
if (strncmp(rd_rel->relname.data, DatumGetCString(key1), NAMEDATALEN) != 0)
{
elog(ERROR, "pg_class_relname_nsp_index is broken, intended tuple with name \"%s\" fetched \"%s\""
" (xmin:%u xmax:%u)",
DatumGetCString(key1), rd_rel->relname.data,
HeapTupleHeaderGetXmin((tuple)->t_data),
HeapTupleHeaderGetXmax((tuple)->t_data));
}
break;
case TYPEOID:
if (HeapTupleGetOid(tuple) != DatumGetObjectId(key1))
{
elog(ERROR, "pg_type_oid_index is broken, oid=%d is pointing to tuple with oid=%d (xmin:%u xmax:%u)",
DatumGetObjectId(key1), HeapTupleGetOid(tuple),
HeapTupleHeaderGetXmin((tuple)->t_data),
HeapTupleHeaderGetXmax((tuple)->t_data));
}
break;
}
}
/*
* SearchCatCache
*
......@@ -1151,6 +1199,17 @@ SearchCatCache(CatCache *cache,
while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
{
/*
* Good place to sanity check the tuple, before adding it to cache.
* So if its fetched using index, lets cross verify tuple intended is the tuple
* fetched. If not fail and contain the damage which maybe caused due to
* index corruption for some reason.
*/
if (scandesc->irel)
{
CrossCheckTuple(cache->id, v1, v2, v3, v4, ntp);
}
ct = CatalogCacheCreateEntry(cache, ntp,
hashValue, hashIndex,
false);
......
......@@ -539,7 +539,6 @@ DeleteGpRelationNodeTuple(
ItemPointerData persistentTid;
int64 persistentSerialNum;
/* Grab an appropriate lock on the gp_relation_node relation */
gp_relation_node = heap_open(GpRelationNodeRelationId, RowExclusiveLock);
tuple = FetchGpRelationNodeTuple(gp_relation_node,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册