diff options
author | Gregory Wlodarek <gregory.wlodarek@mongodb.com> | 2021-02-19 18:16:36 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-02-19 21:11:26 +0000 |
commit | a0b2871db72f0da975c61f50f87839d2ebd14c0a (patch) | |
tree | ffd45a46d4e31d85892b72516c87be476149f2fd /src/mongo/dbtests | |
parent | 6d2adad86ca0ba48e5fa33d5ed43c0385a9e44f1 (diff) | |
download | mongo-a0b2871db72f0da975c61f50f87839d2ebd14c0a.tar.gz |
SERVER-54656 Validation reports missing and extra index entries for clustered collections
Diffstat (limited to 'src/mongo/dbtests')
-rw-r--r-- | src/mongo/dbtests/validate_tests.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/mongo/dbtests/validate_tests.cpp b/src/mongo/dbtests/validate_tests.cpp index fb793a2064c..030c34ca287 100644 --- a/src/mongo/dbtests/validate_tests.cpp +++ b/src/mongo/dbtests/validate_tests.cpp @@ -3575,6 +3575,107 @@ public: } }; +template <bool background> +class ValidateReportInfoOnClusteredCollection : public ValidateBase { +public: + ValidateReportInfoOnClusteredCollection() + : ValidateBase(/*full=*/false, background, /*clustered=*/true) {} + + void run() { + // Cannot run validate with {background:true} if either + // - the RecordStore cursor does not retrieve documents in RecordId order + // - or the storage engine does not support checkpoints. + if (_background && (!_isInRecordIdOrder || !_engineSupportsCheckpoints)) { + return; + } + + lockDb(MODE_X); + CollectionPtr coll = + CollectionCatalog::get(&_opCtx)->lookupCollectionByNamespace(&_opCtx, _nss); + ASSERT(coll); + + // Create an index. + const auto indexName = "a"; + const auto indexKey = BSON("a" << 1); + auto status = dbtests::createIndexFromSpec( + &_opCtx, + coll->ns().ns(), + BSON("name" << indexName << "key" << indexKey << "v" << static_cast<int>(kIndexVersion) + << "background" << false)); + ASSERT_OK(status); + + // Insert documents. + OpDebug* const nullOpDebug = nullptr; + RecordId rid = RecordId::minLong(); + lockDb(MODE_X); + + const OID firstRecordId = OID::gen(); + { + WriteUnitOfWork wunit(&_opCtx); + ASSERT_OK( + coll->insertDocument(&_opCtx, + InsertStatement(BSON("_id" << firstRecordId << "a" << 1)), + nullOpDebug, + true)); + ASSERT_OK(coll->insertDocument(&_opCtx, + InsertStatement(BSON("_id" << OID::gen() << "a" << 2)), + nullOpDebug, + true)); + ASSERT_OK(coll->insertDocument(&_opCtx, + InsertStatement(BSON("_id" << OID::gen() << "a" << 3)), + nullOpDebug, + true)); + rid = coll->getCursor(&_opCtx)->next()->id; + wunit.commit(); + } + releaseDb(); + ensureValidateWorked(); + lockDb(MODE_X); + + RecordStore* rs = coll->getRecordStore(); + + // Updating a document without updating the index entry will cause validation to detect a + // missing index entry and an extra index entry. + { + WriteUnitOfWork wunit(&_opCtx); + auto doc = BSON("_id" << firstRecordId << "a" << 5); + auto updateStatus = rs->updateRecord(&_opCtx, rid, doc.objdata(), doc.objsize()); + ASSERT_OK(updateStatus); + wunit.commit(); + } + releaseDb(); + + { + auto mode = _background ? CollectionValidation::ValidateMode::kBackground + : CollectionValidation::ValidateMode::kForeground; + + ValidateResults results; + BSONObjBuilder output; + + ASSERT_OK(CollectionValidation::validate(&_opCtx, + _nss, + mode, + CollectionValidation::RepairMode::kNone, + &results, + &output, + kTurnOnExtraLoggingForTest)); + + auto dumpOnErrorGuard = makeGuard([&] { + StorageDebugUtil::printValidateResults(results); + StorageDebugUtil::printCollectionAndIndexTableEntries(&_opCtx, coll->ns()); + }); + + ASSERT_EQ(false, results.valid); + ASSERT_EQ(static_cast<size_t>(1), results.errors.size()); + ASSERT_EQ(static_cast<size_t>(2), results.warnings.size()); + ASSERT_EQ(static_cast<size_t>(1), results.extraIndexEntries.size()); + ASSERT_EQ(static_cast<size_t>(1), results.missingIndexEntries.size()); + + dumpOnErrorGuard.dismiss(); + } + } +}; + class ValidateTests : public OldStyleSuiteSpecification { public: ValidateTests() : OldStyleSuiteSpecification("validate_tests") {} @@ -3638,8 +3739,11 @@ public: add<ValidateAddNewMultikeyPaths>(); + // Tests that validation works on clustered collections. add<ValidateInvalidBSONOnClusteredCollection<false>>(); add<ValidateInvalidBSONOnClusteredCollection<true>>(); + add<ValidateReportInfoOnClusteredCollection<false>>(); + add<ValidateReportInfoOnClusteredCollection<true>>(); } }; |