diff options
author | Randolph Tan <randolph@10gen.com> | 2022-02-22 18:33:00 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-16 17:53:27 +0000 |
commit | 8ac94fc68d134eaef7fb3815d25e98ef99f034a3 (patch) | |
tree | 13788b9adf10b34bdd91328acd2fcb486fbcbd25 /src/mongo/db/catalog/index_catalog_impl.cpp | |
parent | b93f3757801f1b452391b8e3c277d092bd0fe835 (diff) | |
download | mongo-8ac94fc68d134eaef7fb3815d25e98ef99f034a3.tar.gz |
SERVER-6491 Prevent dropping shard key index when alternative index doesn't exist
Diffstat (limited to 'src/mongo/db/catalog/index_catalog_impl.cpp')
-rw-r--r-- | src/mongo/db/catalog/index_catalog_impl.cpp | 92 |
1 files changed, 26 insertions, 66 deletions
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp index 115c664d0fc..0104b6bd2d2 100644 --- a/src/mongo/db/catalog/index_catalog_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_impl.cpp @@ -335,8 +335,7 @@ Status IndexCatalogImpl::_isNonIDIndexAndNotAllowedToBuild(OperationContext* opC void IndexCatalogImpl::_logInternalState(OperationContext* opCtx, const CollectionPtr& collection, long long numIndexesInCollectionCatalogEntry, - const std::vector<std::string>& indexNamesToDrop, - bool haveIdIndex) { + const std::vector<std::string>& indexNamesToDrop) { invariant(opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_X)); LOGV2_ERROR(20365, @@ -345,8 +344,7 @@ void IndexCatalogImpl::_logInternalState(OperationContext* opCtx, "numIndexesInCollectionCatalogEntry"_attr = numIndexesInCollectionCatalogEntry, "numReadyIndexes"_attr = _readyIndexes.size(), "numBuildingIndexes"_attr = _buildingIndexes.size(), - "indexNamesToDrop"_attr = indexNamesToDrop, - "haveIdIndex"_attr = haveIdIndex); + "indexNamesToDrop"_attr = indexNamesToDrop); // Report the ready indexes. for (const auto& entry : _readyIndexes) { @@ -1092,15 +1090,15 @@ BSONObj IndexCatalogImpl::getDefaultIdIndexSpec(const CollectionPtr& collection) return b.obj(); } -void IndexCatalogImpl::dropAllIndexes(OperationContext* opCtx, - Collection* collection, - bool includingIdIndex, - std::function<void(const IndexDescriptor*)> onDropFn) { +void IndexCatalogImpl::dropIndexes(OperationContext* opCtx, + Collection* collection, + std::function<bool(const IndexDescriptor*)> matchFn, + std::function<void(const IndexDescriptor*)> onDropFn) { uassert(ErrorCodes::BackgroundOperationInProgressForNamespace, str::stream() << "cannot perform operation: an index build is currently running", !haveAnyIndexesInProgress()); - bool haveIdIndex = false; + bool didExclude = false; invariant(_buildingIndexes.size() == 0); vector<string> indexNamesToDrop; @@ -1110,11 +1108,11 @@ void IndexCatalogImpl::dropAllIndexes(OperationContext* opCtx, while (ii->more()) { seen++; const IndexDescriptor* desc = ii->next()->descriptor(); - if (desc->isIdIndex() && includingIdIndex == false) { - haveIdIndex = true; - continue; + if (matchFn(desc)) { + indexNamesToDrop.push_back(desc->indexName()); + } else { + didExclude = true; } - indexNamesToDrop.push_back(desc->indexName()); } invariant(seen == numIndexesTotal(opCtx)); } @@ -1139,18 +1137,10 @@ void IndexCatalogImpl::dropAllIndexes(OperationContext* opCtx, long long numIndexesInCollectionCatalogEntry = collection->getTotalIndexCount(); - if (haveIdIndex) { - fassert(17324, numIndexesTotal(opCtx) == 1); - fassert(17325, numIndexesReady(opCtx) == 1); - fassert(17326, numIndexesInCollectionCatalogEntry == 1); - fassert(17336, _readyIndexes.size() == 1); - } else { + if (!didExclude) { if (numIndexesTotal(opCtx) || numIndexesInCollectionCatalogEntry || _readyIndexes.size()) { - _logInternalState(opCtx, - collection, - numIndexesInCollectionCatalogEntry, - indexNamesToDrop, - haveIdIndex); + _logInternalState( + opCtx, collection, numIndexesInCollectionCatalogEntry, indexNamesToDrop); } fassert(17327, numIndexesTotal(opCtx) == 0); fassert(17328, numIndexesInCollectionCatalogEntry == 0); @@ -1160,8 +1150,18 @@ void IndexCatalogImpl::dropAllIndexes(OperationContext* opCtx, void IndexCatalogImpl::dropAllIndexes(OperationContext* opCtx, Collection* collection, - bool includingIdIndex) { - dropAllIndexes(opCtx, collection, includingIdIndex, {}); + bool includingIdIndex, + std::function<void(const IndexDescriptor*)> onDropFn) { + dropIndexes(opCtx, + collection, + [includingIdIndex](const IndexDescriptor* indexDescriptor) { + if (includingIdIndex) { + return true; + } + + return !indexDescriptor->isIdIndex(); + }, + onDropFn); } Status IndexCatalogImpl::dropIndex(OperationContext* opCtx, @@ -1375,46 +1375,6 @@ void IndexCatalogImpl::findIndexesByKeyPattern(OperationContext* opCtx, } } -const boost::optional<IndexCatalog::ShardKeyIndex> IndexCatalogImpl::findShardKeyPrefixedIndex( - OperationContext* opCtx, - const CollectionPtr& collection, - const BSONObj& shardKey, - bool requireSingleKey) const { - if (collection->isClustered() && - clustered_util::matchesClusterKey(shardKey, collection->getClusteredInfo())) { - auto clusteredIndexSpec = collection->getClusteredInfo()->getIndexSpec(); - return IndexCatalog::ShardKeyIndex(clusteredIndexSpec); - } - - const IndexDescriptor* best = nullptr; - - std::unique_ptr<IndexIterator> ii = getIndexIterator(opCtx, false); - while (ii->more()) { - const IndexCatalogEntry* entry = ii->next(); - const IndexDescriptor* desc = entry->descriptor(); - bool hasSimpleCollation = desc->collation().isEmpty(); - - if (desc->isPartial() || desc->isSparse()) - continue; - - if (!shardKey.isPrefixOf(desc->keyPattern(), SimpleBSONElementComparator::kInstance)) - continue; - - if (!entry->isMultikey(opCtx, collection) && hasSimpleCollation) { - return IndexCatalog::ShardKeyIndex(desc); - } - - if (!requireSingleKey && hasSimpleCollation) - best = desc; - } - - if (best != nullptr) { - return IndexCatalog::ShardKeyIndex(best); - } - - return boost::none; -} - void IndexCatalogImpl::findIndexByType(OperationContext* opCtx, const string& type, vector<const IndexDescriptor*>& matches, |