summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@mongodb.com>2019-10-04 13:42:44 +0000
committerevergreen <evergreen@mongodb.com>2019-10-04 13:42:44 +0000
commit20a03a3b3c96f54c5ec94a0eac8dcef768e39f43 (patch)
tree3ea3786f6db8a3d70f80ccfcb9109ee8ab358f14 /src/mongo/db/catalog
parentd1c6b36bf04dd90ad963ad5dfbfa491de0c88789 (diff)
downloadmongo-20a03a3b3c96f54c5ec94a0eac8dcef768e39f43.tar.gz
SERVER-43711 ValidateAdaptor::validateIndexKeyCount should not compare in-memory and PIT _id index entry counts
Diffstat (limited to 'src/mongo/db/catalog')
-rw-r--r--src/mongo/db/catalog/collection_validation.cpp5
-rw-r--r--src/mongo/db/catalog/index_consistency.h3
-rw-r--r--src/mongo/db/catalog/validate_adaptor.cpp35
-rw-r--r--src/mongo/db/catalog/validate_adaptor.h19
4 files changed, 29 insertions, 33 deletions
diff --git a/src/mongo/db/catalog/collection_validation.cpp b/src/mongo/db/catalog/collection_validation.cpp
index ae13c779c3f..7be8c43723e 100644
--- a/src/mongo/db/catalog/collection_validation.cpp
+++ b/src/mongo/db/catalog/collection_validation.cpp
@@ -226,10 +226,7 @@ void _validateIndexKeyCount(OperationContext* opCtx,
ValidateResults& curIndexResults = (*indexNsResultsMap)[descriptor->indexName()];
if (curIndexResults.valid) {
- indexValidator->validateIndexKeyCount(
- descriptor,
- validateState->getCollection()->getRecordStore()->numRecords(opCtx),
- curIndexResults);
+ indexValidator->validateIndexKeyCount(descriptor, curIndexResults);
}
}
}
diff --git a/src/mongo/db/catalog/index_consistency.h b/src/mongo/db/catalog/index_consistency.h
index 78556234b94..472025e6e0b 100644
--- a/src/mongo/db/catalog/index_consistency.h
+++ b/src/mongo/db/catalog/index_consistency.h
@@ -30,11 +30,8 @@
#pragma once
#include "mongo/bson/simple_bsonobj_comparator.h"
-#include "mongo/db/catalog/collection_validation.h"
-#include "mongo/db/catalog/throttle_cursor.h"
#include "mongo/db/catalog/validate_state.h"
#include "mongo/db/storage/key_string.h"
-#include "mongo/db/storage/record_store.h"
namespace mongo {
diff --git a/src/mongo/db/catalog/validate_adaptor.cpp b/src/mongo/db/catalog/validate_adaptor.cpp
index 7d43c3edc13..524719dd5c4 100644
--- a/src/mongo/db/catalog/validate_adaptor.cpp
+++ b/src/mongo/db/catalog/validate_adaptor.cpp
@@ -37,12 +37,14 @@
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/index_catalog.h"
#include "mongo/db/catalog/index_consistency.h"
+#include "mongo/db/catalog/throttle_cursor.h"
#include "mongo/db/index/index_access_method.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/index/wildcard_access_method.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/storage/key_string.h"
+#include "mongo/db/storage/record_store.h"
#include "mongo/rpc/object_check.h"
#include "mongo/util/log.h"
@@ -210,7 +212,7 @@ void ValidateAdaptor::traverseIndex(OperationContext* opCtx,
void ValidateAdaptor::traverseRecordStore(OperationContext* opCtx,
ValidateResults* results,
BSONObjBuilder* output) {
- long long nrecords = 0;
+ _numRecords = 0; // need to reset it because this function can be called more than once.
long long dataSizeTotal = 0;
long long interruptIntervalNumBytes = 0;
long long nInvalid = 0;
@@ -224,9 +226,9 @@ void ValidateAdaptor::traverseRecordStore(OperationContext* opCtx,
traverseRecordStoreCursor->seekExact(opCtx, _validateState->getFirstRecordId());
record;
record = traverseRecordStoreCursor->next(opCtx)) {
- ++nrecords;
+ ++_numRecords;
interruptIntervalNumBytes += record->data.size();
- if (nrecords % kInterruptIntervalNumRecords == 0 ||
+ if (_numRecords % kInterruptIntervalNumRecords == 0 ||
interruptIntervalNumBytes >= kInterruptIntervalNumBytes) {
opCtx->checkForInterrupt();
@@ -281,29 +283,29 @@ void ValidateAdaptor::traverseRecordStore(OperationContext* opCtx,
// checkpoint and it may not have the most up-to-date changes.
if (results->valid && !_validateState->isBackground()) {
_validateState->getCollection()->getRecordStore()->updateStatsAfterRepair(
- opCtx, nrecords, dataSizeTotal);
+ opCtx, _numRecords, dataSizeTotal);
}
output->appendNumber("nInvalidDocuments", nInvalid);
- output->appendNumber("nrecords", nrecords);
+ output->appendNumber("nrecords", _numRecords);
}
-void ValidateAdaptor::validateIndexKeyCount(const IndexDescriptor* idx,
- int64_t numRecs,
- ValidateResults& results) {
+void ValidateAdaptor::validateIndexKeyCount(const IndexDescriptor* idx, ValidateResults& results) {
+ // Fetch the total number of index entries we previously found traversing the index.
const std::string indexName = idx->indexName();
IndexInfo* indexInfo = &_indexConsistency->getIndexInfo(indexName);
auto numTotalKeys = indexInfo->numKeys;
+ // Do not fail on finding too few index entries compared to collection entries when full:false.
bool hasTooFewKeys = false;
bool noErrorOnTooFewKeys = !_validateState->isFullValidate();
- if (idx->isIdIndex() && numTotalKeys != numRecs) {
- hasTooFewKeys = numTotalKeys < numRecs ? true : hasTooFewKeys;
+ if (idx->isIdIndex() && numTotalKeys != _numRecords) {
+ hasTooFewKeys = numTotalKeys < _numRecords ? true : hasTooFewKeys;
std::string msg = str::stream()
<< "number of _id index entries (" << numTotalKeys
- << ") does not match the number of documents in the index (" << numRecs << ")";
- if (noErrorOnTooFewKeys && (numTotalKeys < numRecs)) {
+ << ") does not match the number of documents in the index (" << _numRecords << ")";
+ if (noErrorOnTooFewKeys && (numTotalKeys < _numRecords)) {
results.warnings.push_back(msg);
} else {
results.errors.push_back(msg);
@@ -316,21 +318,22 @@ void ValidateAdaptor::validateIndexKeyCount(const IndexDescriptor* idx,
// produce an index key per array entry) and not $** indexes which can produce index keys for
// multiple paths within a single document.
if (results.valid && !idx->isMultikey() && idx->getIndexType() != IndexType::INDEX_WILDCARD &&
- numTotalKeys > numRecs) {
+ numTotalKeys > _numRecords) {
std::string err = str::stream()
<< "index " << idx->indexName() << " is not multi-key, but has more entries ("
- << numTotalKeys << ") than documents in the index (" << numRecs << ")";
+ << numTotalKeys << ") than documents in the index (" << _numRecords << ")";
results.errors.push_back(err);
results.valid = false;
}
+
// Ignore any indexes with a special access method. If an access method name is given, the
// index may be a full text, geo or special index plugin with different semantics.
if (results.valid && !idx->isSparse() && !idx->isPartial() && !idx->isIdIndex() &&
- idx->getAccessMethodName() == "" && numTotalKeys < numRecs) {
+ idx->getAccessMethodName() == "" && numTotalKeys < _numRecords) {
hasTooFewKeys = true;
std::string msg = str::stream()
<< "index " << idx->indexName() << " is not sparse or partial, but has fewer entries ("
- << numTotalKeys << ") than documents in the index (" << numRecs << ")";
+ << numTotalKeys << ") than documents in the index (" << _numRecords << ")";
if (noErrorOnTooFewKeys) {
results.warnings.push_back(msg);
} else {
diff --git a/src/mongo/db/catalog/validate_adaptor.h b/src/mongo/db/catalog/validate_adaptor.h
index b68a6f37618..c035cb167e0 100644
--- a/src/mongo/db/catalog/validate_adaptor.h
+++ b/src/mongo/db/catalog/validate_adaptor.h
@@ -29,11 +29,7 @@
#pragma once
-#include "mongo/db/catalog/collection_validation.h"
-#include "mongo/db/catalog/throttle_cursor.h"
#include "mongo/db/catalog/validate_state.h"
-#include "mongo/db/storage/record_store.h"
-#include "mongo/db/storage/sorted_data_interface.h"
namespace mongo {
@@ -42,8 +38,8 @@ class IndexDescriptor;
class OperationContext;
/**
- * The record store validate adaptor is used to keep track of the index consistency during
- * a validation that's running.
+ * The validate adaptor is used to keep track of collection and index consistency during a running
+ * collection validation operation.
*/
class ValidateAdaptor {
using ValidateResultsMap = std::map<std::string, ValidateResults>;
@@ -84,15 +80,18 @@ public:
BSONObjBuilder* output);
/**
- * Validate that the number of document keys matches the number of index keys.
+ * Validates that the number of document keys matches the number of index keys previously
+ * traversed in traverseIndex().
*/
- void validateIndexKeyCount(const IndexDescriptor* idx,
- int64_t numRecs,
- ValidateResults& results);
+ void validateIndexKeyCount(const IndexDescriptor* idx, ValidateResults& results);
private:
IndexConsistency* _indexConsistency;
CollectionValidation::ValidateState* _validateState;
ValidateResultsMap* _indexNsResultsMap;
+
+ // Saves the record count from the record store traversal to be used later to validate the index
+ // entries count. Reset every time traverseRecordStore() is called.
+ long long _numRecords = 0;
};
} // namespace mongo