diff options
author | Geert Bosch <geert@mongodb.com> | 2019-06-04 11:34:41 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2019-06-12 00:28:28 -0400 |
commit | 5a9b37f17c46989502049c320bfdddc2042c8182 (patch) | |
tree | 8b3c830e9b9e90f3621b884e5daae950a41d3ebb | |
parent | 4e8325dc85f8caba7255ee7418c50f0551360bbd (diff) | |
download | mongo-5a9b37f17c46989502049c320bfdddc2042c8182.tar.gz |
SERVER-41538 Remove indirection through indexNumber in IndexConsistency
-rw-r--r-- | src/mongo/db/catalog/index_consistency.cpp | 97 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_consistency.h | 57 | ||||
-rw-r--r-- | src/mongo/db/catalog/private/record_store_validate_adaptor.cpp | 24 |
3 files changed, 47 insertions, 131 deletions
diff --git a/src/mongo/db/catalog/index_consistency.cpp b/src/mongo/db/catalog/index_consistency.cpp index 7e4eacbe9d1..bb225ab5878 100644 --- a/src/mongo/db/catalog/index_consistency.cpp +++ b/src/mongo/db/catalog/index_consistency.cpp @@ -84,8 +84,7 @@ IndexConsistency::IndexConsistency(OperationContext* opCtx, IndexInfo indexInfo; - indexInfo.indexName = indexName; - indexInfo.keyPattern = descriptor->keyPattern(); + indexInfo.descriptor = descriptor; indexInfo.isReady = _collection->getCatalogEntry()->isIndexReady(opCtx, indexName); uint32_t indexNameHash; @@ -96,47 +95,14 @@ IndexConsistency::IndexConsistency(OperationContext* opCtx, indexInfo.numKeys = 0; indexInfo.numLongKeys = 0; indexInfo.numRecords = 0; - indexInfo.numExtraIndexKeys = 0; _indexesInfo.push_back(indexInfo); } } -void IndexConsistency::addLongIndexKey(int indexNumber) { - - if (indexNumber < 0 || indexNumber >= static_cast<int>(_indexesInfo.size())) { - return; - } - - _indexesInfo[indexNumber].numRecords++; - _indexesInfo[indexNumber].numLongKeys++; -} - -int64_t IndexConsistency::getNumKeys(int indexNumber) const { - - if (indexNumber < 0 || indexNumber >= static_cast<int>(_indexesInfo.size())) { - return 0; - } - - return _indexesInfo.at(indexNumber).numKeys; -} - -int64_t IndexConsistency::getNumLongKeys(int indexNumber) const { - - if (indexNumber < 0 || indexNumber >= static_cast<int>(_indexesInfo.size())) { - return 0; - } - - return _indexesInfo.at(indexNumber).numLongKeys; -} - -int64_t IndexConsistency::getNumRecords(int indexNumber) const { - - if (indexNumber < 0 || indexNumber >= static_cast<int>(_indexesInfo.size())) { - return 0; - } - - return _indexesInfo.at(indexNumber).numRecords; +void IndexConsistency::addLongIndexKey(IndexInfo* indexInfo) { + indexInfo->numRecords++; + indexInfo->numLongKeys++; } bool IndexConsistency::haveEntryMismatch() const { @@ -144,25 +110,6 @@ bool IndexConsistency::haveEntryMismatch() const { _indexKeyCount.begin(), _indexKeyCount.end(), [](int count) -> bool { return count; }); } -int64_t IndexConsistency::getNumExtraIndexKeys(int indexNumber) const { - - if (indexNumber < 0 || indexNumber >= static_cast<int>(_indexesInfo.size())) { - return 0; - } - - return _indexesInfo.at(indexNumber).numExtraIndexKeys; -} - -int IndexConsistency::getIndexNumber(const std::string& indexName) { - - auto search = _indexNumber.find(indexName); - if (search != _indexNumber.end()) { - return search->second; - } - - return -1; -} - void IndexConsistency::setSecondPhase() { invariant(_firstPhase); @@ -265,22 +212,22 @@ void IndexConsistency::addIndexEntryErrors(ValidateResultsMap* indexNsResultsMap } void IndexConsistency::addDocKey(const KeyString& ks, - int indexNumber, - const RecordId& recordId, + IndexInfo* indexInfo, + RecordId recordId, const BSONObj& indexKey) { // Ignore indexes that weren't ready before we started validation. - if (!_indexesInfo.at(indexNumber).isReady) { + if (!indexInfo->isReady) { return; } - const uint32_t hash = _hashKeyString(ks, indexNumber); + const uint32_t hash = _hashKeyString(ks, indexInfo->indexNameHash); if (_firstPhase) { // During the first phase of validation we only keep track of the count for the document // keys encountered. _indexKeyCount[hash]++; - _indexesInfo.at(indexNumber).numRecords++; + indexInfo->numRecords++; } else if (_indexKeyCount[hash]) { // Found a document key for a hash bucket that had mismatches. @@ -296,7 +243,7 @@ void IndexConsistency::addDocKey(const KeyString& ks, } std::string key = std::string(ks.getBuffer(), ks.getSize()); - BSONObj info = _generateInfo(indexNumber, recordId, indexKey, idKey); + BSONObj info = _generateInfo(*indexInfo, recordId, indexKey, idKey); // Cannot have duplicate KeyStrings during the document scan phase. invariant(_missingIndexEntries.count(key) == 0); @@ -305,22 +252,22 @@ void IndexConsistency::addDocKey(const KeyString& ks, } void IndexConsistency::addIndexKey(const KeyString& ks, - int indexNumber, - const RecordId& recordId, + IndexInfo* indexInfo, + RecordId recordId, const BSONObj& indexKey) { // Ignore indexes that weren't ready before we started validation. - if (!_indexesInfo.at(indexNumber).isReady) { + if (!indexInfo->isReady) { return; } - const uint32_t hash = _hashKeyString(ks, indexNumber); + const uint32_t hash = _hashKeyString(ks, indexInfo->indexNameHash); if (_firstPhase) { // During the first phase of validation we only keep track of the count for the index entry // keys encountered. _indexKeyCount[hash]--; - _indexesInfo.at(indexNumber).numKeys++; + indexInfo->numKeys++; } else if (_indexKeyCount[hash]) { // Found an index key for a bucket that has inconsistencies. // If there is a corresponding document key for the index entry key, we remove the key from @@ -328,7 +275,7 @@ void IndexConsistency::addIndexKey(const KeyString& ks, // key, we add the key to the '_extraIndexEntries' map. std::string key = std::string(ks.getBuffer(), ks.getSize()); - BSONObj info = _generateInfo(indexNumber, recordId, indexKey, boost::none); + BSONObj info = _generateInfo(*indexInfo, recordId, indexKey, boost::none); if (_missingIndexEntries.count(key) == 0) { // We may have multiple extra index entries for a given KeyString. @@ -346,12 +293,12 @@ void IndexConsistency::addIndexKey(const KeyString& ks, } } -BSONObj IndexConsistency::_generateInfo(const int& indexNumber, - const RecordId& recordId, +BSONObj IndexConsistency::_generateInfo(const IndexInfo& indexInfo, + RecordId recordId, const BSONObj& indexKey, boost::optional<BSONElement> idKey) { - const std::string& indexName = _indexesInfo.at(indexNumber).indexName; - const BSONObj& keyPattern = _indexesInfo.at(indexNumber).keyPattern; + const std::string& indexName = indexInfo.descriptor->indexName(); + const BSONObj& keyPattern = indexInfo.descriptor->keyPattern(); // We need to rehydrate the indexKey for improved readability. // {"": ObjectId(...)} -> {"_id": ObjectId(...)} @@ -379,9 +326,7 @@ BSONObj IndexConsistency::_generateInfo(const int& indexNumber, } } -uint32_t IndexConsistency::_hashKeyString(const KeyString& ks, int indexNumber) const { - - uint32_t indexNameHash = _indexesInfo.at(indexNumber).indexNameHash; +uint32_t IndexConsistency::_hashKeyString(const KeyString& ks, uint32_t indexNameHash) const { MurmurHash3_x86_32( ks.getTypeBits().getBuffer(), ks.getTypeBits().getSize(), indexNameHash, &indexNameHash); MurmurHash3_x86_32(ks.getBuffer(), ks.getSize(), indexNameHash, &indexNameHash); diff --git a/src/mongo/db/catalog/index_consistency.h b/src/mongo/db/catalog/index_consistency.h index b039505a82e..2d28a2f2cc8 100644 --- a/src/mongo/db/catalog/index_consistency.h +++ b/src/mongo/db/catalog/index_consistency.h @@ -51,10 +51,7 @@ namespace mongo { * Contains all the index information and stats throughout the validation. */ struct IndexInfo { - // The name of the index. - std::string indexName; - // The index key pattern. - BSONObj keyPattern; + const IndexDescriptor* descriptor; // Informs us if the index was ready or not for consumption during the start of validation. bool isReady; // Contains the pre-computed hash of the index name. @@ -68,9 +65,6 @@ struct IndexInfo { // The number of records that have a key in their document that referenced back to the // this index int64_t numRecords; - // Keeps track of how many indexes were removed (-1) and added (+1) after the - // point of validity was set for this index. - int64_t numExtraIndexKeys; }; class IndexConsistency final { @@ -91,8 +85,8 @@ public: * inconsistent hash buckets during the first phase of validation. */ void addDocKey(const KeyString& ks, - int indexNumber, - const RecordId& recordId, + IndexInfo* indexInfo, + RecordId recordId, const BSONObj& indexKey); /** @@ -102,30 +96,15 @@ public: * inconsistent hash buckets during the first phase of validation to document keys. */ void addIndexKey(const KeyString& ks, - int indexNumber, - const RecordId& recordId, + IndexInfo* indexInfo, + RecordId recordId, const BSONObj& indexKey); /** * Add one to the `_longKeys` count for the given `indexNs`. * This is required because index keys > `KeyString::kMaxKeyBytes` are not indexed. */ - void addLongIndexKey(int indexNumber); - - /** - * Returns the number of index entries for the given `indexNs`. - */ - int64_t getNumKeys(int indexNumber) const; - - /** - * Returns the number of long keys that were not indexed for the given `indexNs`. - */ - int64_t getNumLongKeys(int indexNumber) const; - - /** - * Return the number of records with keys for the given `indexNs`. - */ - int64_t getNumRecords(int indexNumber) const; + void addLongIndexKey(IndexInfo* indexInfo); /** * Returns true if any value in the `_indexKeyCount` map is not equal to 0, otherwise @@ -134,18 +113,14 @@ public: bool haveEntryMismatch() const; /** - * Index entries may be added or removed by concurrent writes during the index scan phase, - * after establishing the point of validity. We need to account for these additions and - * removals so that when we validate the index key count, we also have a pre-image of the - * index counts and won't get incorrect results because of the extra index entries we may or - * may not have scanned. - */ - int64_t getNumExtraIndexKeys(int indexNumber) const; - - /** - * Returns the index number for the corresponding index name. + * Return info on all indexes tracked by this. */ - int getIndexNumber(const std::string& indexName); + std::vector<IndexInfo>& getIndexInfo() { + return _indexesInfo; + } + IndexInfo& getIndexInfo(const std::string& indexName) { + return _indexesInfo.at(_indexNumber.at(indexName)); + } /** * Informs the IndexConsistency object that we're advancing to the second phase of index @@ -243,15 +218,15 @@ private: * } * } */ - BSONObj _generateInfo(const int& indexNumber, - const RecordId& recordId, + BSONObj _generateInfo(const IndexInfo& indexInfo, + RecordId recordId, const BSONObj& indexKey, boost::optional<BSONElement> idKey); /** * Returns a hashed value from the given KeyString and index namespace. */ - uint32_t _hashKeyString(const KeyString& ks, int indexNumbers) const; + uint32_t _hashKeyString(const KeyString& ks, uint32_t indexNameHash) const; }; // IndexConsistency } // namespace mongo diff --git a/src/mongo/db/catalog/private/record_store_validate_adaptor.cpp b/src/mongo/db/catalog/private/record_store_validate_adaptor.cpp index 617f4093804..ad4c3875379 100644 --- a/src/mongo/db/catalog/private/record_store_validate_adaptor.cpp +++ b/src/mongo/db/catalog/private/record_store_validate_adaptor.cpp @@ -65,12 +65,9 @@ Status RecordStoreValidateAdaptor::validate(const RecordId& recordId, return status; } - IndexCatalog::IndexIterator i = _indexCatalog->getIndexIterator(_opCtx, false); - - while (i.more()) { - const IndexDescriptor* descriptor = i.next(); + for (auto& indexInfo : _indexConsistency->getIndexInfo()) { + const IndexDescriptor* descriptor = indexInfo.descriptor; const std::string indexName = descriptor->indexName(); - int indexNumber = _indexConsistency->getIndexNumber(indexName); ValidateResults curRecordResults; const IndexAccessMethod* iam = _indexCatalog->getIndex(descriptor); @@ -108,12 +105,12 @@ Status RecordStoreValidateAdaptor::validate(const RecordId& recordId, for (const auto& key : documentKeySet) { if (key.objsize() >= static_cast<int64_t>(KeyString::TypeBits::kMaxKeyBytes)) { // Index keys >= 1024 bytes are not indexed. - _indexConsistency->addLongIndexKey(indexNumber); + _indexConsistency->addLongIndexKey(&indexInfo); continue; } ks.resetToKey(key, ord, recordId); - _indexConsistency->addDocKey(ks, indexNumber, recordId, key); + _indexConsistency->addDocKey(ks, &indexInfo, recordId, key); } (*_indexNsResultsMap)[indexName] = curRecordResults; } @@ -125,7 +122,7 @@ void RecordStoreValidateAdaptor::traverseIndex(const IndexAccessMethod* iam, ValidateResults* results, int64_t* numTraversedKeys) { auto indexName = descriptor->indexName(); - int indexNumber = _indexConsistency->getIndexNumber(indexName); + IndexInfo* indexInfo = &_indexConsistency->getIndexInfo(indexName); int64_t numKeys = 0; const auto& key = descriptor->keyPattern(); @@ -146,8 +143,7 @@ void RecordStoreValidateAdaptor::traverseIndex(const IndexAccessMethod* iam, if (!isFirstEntry && *indexKeyString < *prevIndexKeyString) { if (results && results->valid) { results->errors.push_back( - "one or more indexes are not in strictly ascending or descending " - "order"); + "one or more indexes are not in strictly ascending or descending order"); } if (results) { @@ -156,7 +152,7 @@ void RecordStoreValidateAdaptor::traverseIndex(const IndexAccessMethod* iam, } _indexConsistency->addIndexKey( - *indexKeyString, indexNumber, indexEntry->loc, indexEntry->key); + *indexKeyString, indexInfo, indexEntry->loc, indexEntry->key); numKeys++; isFirstEntry = false; @@ -226,9 +222,9 @@ void RecordStoreValidateAdaptor::validateIndexKeyCount(IndexDescriptor* idx, int64_t numRecs, ValidateResults& results) { const std::string indexName = idx->indexName(); - int indexNumber = _indexConsistency->getIndexNumber(indexName); - int64_t numIndexedKeys = _indexConsistency->getNumKeys(indexNumber); - int64_t numLongKeys = _indexConsistency->getNumLongKeys(indexNumber); + IndexInfo* indexInfo = &_indexConsistency->getIndexInfo(indexName); + int64_t numIndexedKeys = indexInfo->numKeys; + int64_t numLongKeys = indexInfo->numLongKeys; auto totalKeys = numLongKeys + numIndexedKeys; bool hasTooFewKeys = false; |