From 1f0ad40656fc0cca935cd20038064e6281a55d30 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 19 Apr 2011 16:58:53 -0400 Subject: [PATCH] Revert "Prevent incorrect updates of pg_index while reindexing pg_index itself." This reverts commit 8835284e0d903156632f76eea941cf5c592717ec of 2011-04-15. There's a better way to do it, which will follow shortly. --- src/backend/catalog/index.c | 69 +++++++++++-------------------------- 1 file changed, 21 insertions(+), 48 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 79b96a07d8..487dbbf24d 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1423,13 +1423,6 @@ index_build(Relation heapRelation, HeapTuple indexTuple; Form_pg_index indexForm; - /* - * Broken HOT chains should not get reported in system catalogs; in - * particular it would be quite dangerous to try to modify the index's - * pg_index entry if we are reindexing pg_index itself. - */ - Assert(!IsSystemRelation(heapRelation)); - pg_index = heap_open(IndexRelationId, RowExclusiveLock); indexTuple = SearchSysCacheCopy(INDEXRELID, @@ -1489,13 +1482,7 @@ index_build(Relation heapRelation, * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect * any potentially broken HOT chains. Currently, we set this if there are * any RECENTLY_DEAD entries in a HOT chain, without trying very hard to - * detect whether they're really incompatible with the chain tip. However, - * we do not ever set ii_BrokenHotChain true when the relation is a system - * catalog. This is to avoid problematic behavior when reindexing pg_index - * itself: we can't safely change the index's indcheckxmin field when we're - * partway through such an operation. It should be okay since the set of - * indexes on a system catalog ought not change during concurrent operations, - * so that no HOT chain in it could ever become broken. + * detect whether they're really incompatible with the chain tip. */ double IndexBuildHeapScan(Relation heapRelation, @@ -1505,7 +1492,6 @@ IndexBuildHeapScan(Relation heapRelation, IndexBuildCallback callback, void *callback_state) { - bool is_system_catalog; HeapScanDesc scan; HeapTuple heapTuple; Datum values[INDEX_MAX_KEYS]; @@ -1525,9 +1511,6 @@ IndexBuildHeapScan(Relation heapRelation, */ Assert(OidIsValid(indexRelation->rd_rel->relam)); - /* Remember if it's a system catalog */ - is_system_catalog = IsSystemRelation(heapRelation); - /* * Need an EState for evaluation of index expressions and partial-index * predicates. Also a slot to hold the current tuple. @@ -1666,8 +1649,7 @@ IndexBuildHeapScan(Relation heapRelation, { indexIt = false; /* mark the index as unsafe for old snapshots */ - if (!is_system_catalog) - indexInfo->ii_BrokenHotChain = true; + indexInfo->ii_BrokenHotChain = true; } else if (indexInfo->ii_BrokenHotChain) indexIt = false; @@ -1756,8 +1738,7 @@ IndexBuildHeapScan(Relation heapRelation, { indexIt = false; /* mark the index as unsafe for old snapshots */ - if (!is_system_catalog) - indexInfo->ii_BrokenHotChain = true; + indexInfo->ii_BrokenHotChain = true; } else if (indexInfo->ii_BrokenHotChain) indexIt = false; @@ -2371,35 +2352,27 @@ reindex_index(Oid indexId) * We can also reset indcheckxmin, because we have now done a * non-concurrent index build, *except* in the case where index_build * found some still-broken HOT chains. - * - * When reindexing a system catalog, don't do any of this --- it would be - * particularly risky to try to modify pg_index while we are reindexing - * pg_index itself. We don't support CREATE INDEX CONCURRENTLY on system - * catalogs anyway, and they should never have indcheckxmin set either. */ - if (!IsSystemRelation(heapRelation)) + pg_index = heap_open(IndexRelationId, RowExclusiveLock); + + indexTuple = SearchSysCacheCopy(INDEXRELID, + ObjectIdGetDatum(indexId), + 0, 0, 0); + if (!HeapTupleIsValid(indexTuple)) + elog(ERROR, "cache lookup failed for index %u", indexId); + indexForm = (Form_pg_index) GETSTRUCT(indexTuple); + + if (!indexForm->indisvalid || !indexForm->indisready || + (indexForm->indcheckxmin && !indexInfo->ii_BrokenHotChain)) { - pg_index = heap_open(IndexRelationId, RowExclusiveLock); - - indexTuple = SearchSysCacheCopy(INDEXRELID, - ObjectIdGetDatum(indexId), - 0, 0, 0); - if (!HeapTupleIsValid(indexTuple)) - elog(ERROR, "cache lookup failed for index %u", indexId); - indexForm = (Form_pg_index) GETSTRUCT(indexTuple); - - if (!indexForm->indisvalid || !indexForm->indisready || - (indexForm->indcheckxmin && !indexInfo->ii_BrokenHotChain)) - { - indexForm->indisvalid = true; - indexForm->indisready = true; - if (!indexInfo->ii_BrokenHotChain) - indexForm->indcheckxmin = false; - simple_heap_update(pg_index, &indexTuple->t_self, indexTuple); - CatalogUpdateIndexes(pg_index, indexTuple); - } - heap_close(pg_index, RowExclusiveLock); + indexForm->indisvalid = true; + indexForm->indisready = true; + if (!indexInfo->ii_BrokenHotChain) + indexForm->indcheckxmin = false; + simple_heap_update(pg_index, &indexTuple->t_self, indexTuple); + CatalogUpdateIndexes(pg_index, indexTuple); } + heap_close(pg_index, RowExclusiveLock); /* Close rels, but keep locks */ index_close(iRel, NoLock);