From 0ff952e755f4a4dab50faf425ce491096e66cad2 Mon Sep 17 00:00:00 2001 From: Ashwin Agrawal Date: Fri, 4 Mar 2016 09:21:05 -0800 Subject: [PATCH] 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. --- src/backend/utils/cache/catcache.c | 59 ++++++++++++++++++++++++++++++ src/backend/utils/cache/relcache.c | 1 - 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 6278d79c9e..918c33e788 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -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); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 950794ab0b..8948d4db30 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -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, -- GitLab