summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2019-06-04 11:34:41 -0400
committerGeert Bosch <geert@mongodb.com>2019-06-12 00:28:28 -0400
commit5a9b37f17c46989502049c320bfdddc2042c8182 (patch)
tree8b3c830e9b9e90f3621b884e5daae950a41d3ebb
parent4e8325dc85f8caba7255ee7418c50f0551360bbd (diff)
downloadmongo-5a9b37f17c46989502049c320bfdddc2042c8182.tar.gz
SERVER-41538 Remove indirection through indexNumber in IndexConsistency
-rw-r--r--src/mongo/db/catalog/index_consistency.cpp97
-rw-r--r--src/mongo/db/catalog/index_consistency.h57
-rw-r--r--src/mongo/db/catalog/private/record_store_validate_adaptor.cpp24
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;