diff options
author | Josef Ahmad <josef.ahmad@mongodb.com> | 2021-12-14 10:00:38 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-12-17 17:14:22 +0000 |
commit | 87d16bbe9001824aa779a12d63b6ee7fe08b5830 (patch) | |
tree | efecb9c8e03b79f097aed318f197e4ee67d1cd35 | |
parent | dac8910e21e7e8835087167a6135e10257a7645b (diff) | |
download | mongo-87d16bbe9001824aa779a12d63b6ee7fe08b5830.tar.gz |
SERVER-61877 Remove catalog consistency verification from dbCheck
(cherry picked from commit a7769499d4f46deb5c52cacad15c499a70e42683)
-rw-r--r-- | jstests/replsets/dbcheck.js | 36 | ||||
-rw-r--r-- | src/mongo/db/commands/dbcheck.cpp | 66 | ||||
-rw-r--r-- | src/mongo/db/repl/dbcheck.cpp | 147 | ||||
-rw-r--r-- | src/mongo/db/repl/dbcheck.h | 37 |
4 files changed, 4 insertions, 282 deletions
diff --git a/jstests/replsets/dbcheck.js b/jstests/replsets/dbcheck.js index 3cdc784d6f2..54844fb0d59 100644 --- a/jstests/replsets/dbcheck.js +++ b/jstests/replsets/dbcheck.js @@ -415,43 +415,7 @@ function simpleTestCatchesExtra() { JSON.stringify(errors.toArray())); } -// Test that dbCheck catches an extra index on the secondary. -function testCollectionMetadataChanges() { - { - const primary = replSet.getPrimary(); - const db = primary.getDB(dbName); - db[collName].drop(); - clearLog(); - - // Create the collection on the primary. - db.createCollection(collName, {validationLevel: "off"}); - } - - replSet.awaitReplication(); - injectInconsistencyOnSecondary( - {createIndexes: collName, indexes: [{key: {whatever: 1}, name: "whatever"}]}); - replSet.awaitReplication(); - - { - const primary = replSet.getPrimary(); - const db = primary.getDB(dbName); - assert.commandWorked(db.runCommand({dbCheck: collName})); - awaitDbCheckCompletion(db, collName); - } - - const errors = replSet.getSecondary().getDB("local").system.healthlog.find( - {"operation": /dbCheck.*/, "severity": "error", "data.success": true}); - - assert.eq(errors.count(), - 1, - "expected exactly 1 inconsistency after single inconsistent index creation, found: " + - JSON.stringify(errors.toArray())); - - clearLog(); -} - simpleTestCatchesExtra(); -testCollectionMetadataChanges(); replSet.stopSet(); })(); diff --git a/src/mongo/db/commands/dbcheck.cpp b/src/mongo/db/commands/dbcheck.cpp index d8a1aa510a8..44485d798b0 100644 --- a/src/mongo/db/commands/dbcheck.cpp +++ b/src/mongo/db/commands/dbcheck.cpp @@ -187,10 +187,8 @@ protected: private: void _doCollection(const DbCheckCollectionInfo& info) { - // If we can't find the collection, abort the check. - if (!_getCollectionMetadata(info)) { - return; - } + // The collection was confirmed as existing in singleCollectionRun(). + // runBatch() will handle the case of the collection having been dropped since then. if (_done) { return; @@ -285,66 +283,6 @@ private: std::string _dbName; std::unique_ptr<DbCheckRun> _run; - bool _getCollectionMetadata(const DbCheckCollectionInfo& info) { - auto uniqueOpCtx = Client::getCurrent()->makeOperationContext(); - auto opCtx = uniqueOpCtx.get(); - - // While we get the prev/next UUID information, we need a database-level lock. - AutoGetDb agd(opCtx, info.nss.db(), MODE_S); - - if (_stepdownHasOccurred(opCtx, info.nss)) { - _done = true; - return true; - } - - auto db = agd.getDb(); - if (!db) { - return false; - } - - auto collection = - CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, info.nss); - if (!collection) { - return false; - } - - auto [prev, next] = getPrevAndNextUUIDs(opCtx, collection); - - // Find and report collection metadata. - auto indices = collectionIndexInfo(opCtx, collection); - auto options = collectionOptions(opCtx, collection); - - DbCheckOplogCollection entry; - entry.setNss(collection->ns()); - entry.setUuid(collection->uuid()); - if (prev) { - entry.setPrev(*prev); - } - if (next) { - entry.setNext(*next); - } - entry.setType(OplogEntriesEnum::Collection); - entry.setIndexes(indices); - entry.setOptions(options); - - // Send information on this collection over the oplog for the secondary to check. - auto optime = _logOp(opCtx, collection->ns(), collection->uuid(), entry.toBSON()); - - DbCheckCollectionInformation collectionInfo; - collectionInfo.collectionName = collection->ns().coll().toString(); - collectionInfo.prev = entry.getPrev(); - collectionInfo.next = entry.getNext(); - collectionInfo.indexes = entry.getIndexes(); - collectionInfo.options = entry.getOptions(); - - auto hle = dbCheckCollectionEntry( - collection->ns(), collection->uuid(), collectionInfo, collectionInfo, optime); - - HealthLog::get(opCtx).log(*hle); - - return true; - } - StatusWith<BatchStats> _runBatch(const DbCheckCollectionInfo& info, const BSONKey& first, int64_t batchDocs, diff --git a/src/mongo/db/repl/dbcheck.cpp b/src/mongo/db/repl/dbcheck.cpp index 24ae654045e..6853c45a044 100644 --- a/src/mongo/db/repl/dbcheck.cpp +++ b/src/mongo/db/repl/dbcheck.cpp @@ -226,77 +226,6 @@ void maybeAppend(md5_state_t* state, const boost::optional<UUID>& uuid) { } } -std::string hashCollectionInfo(const DbCheckCollectionInformation& info) { - md5_state_t state; - md5_init(&state); - - md5_append(&state, md5Cast(info.collectionName.data()), info.collectionName.size()); - - maybeAppend(&state, info.prev); - maybeAppend(&state, info.next); - - for (const auto& index : info.indexes) { - md5_append(&state, md5Cast(index.objdata()), index.objsize()); - } - - md5_append(&state, md5Cast(info.options.objdata()), info.options.objsize()); - - md5digest digest; - - md5_finish(&state, digest); - return digestToString(digest); -} - -std::pair<boost::optional<UUID>, boost::optional<UUID>> getPrevAndNextUUIDs( - OperationContext* opCtx, Collection* collection) { - const CollectionCatalog& catalog = CollectionCatalog::get(opCtx); - const UUID uuid = collection->uuid(); - - std::vector<CollectionUUID> collectionUUIDs = - catalog.getAllCollectionUUIDsFromDb(collection->ns().db()); - auto uuidIt = std::find(collectionUUIDs.begin(), collectionUUIDs.end(), uuid); - invariant(uuidIt != collectionUUIDs.end()); - - boost::optional<UUID> prevUUID; - boost::optional<UUID> nextUUID; - - if (uuidIt != collectionUUIDs.begin()) { - prevUUID = *std::prev(uuidIt); - } - - if (auto nextIt = std::next(uuidIt); nextIt != collectionUUIDs.end()) { - nextUUID = *nextIt; - } - - return std::make_pair(prevUUID, nextUUID); -} - -std::unique_ptr<HealthLogEntry> dbCheckCollectionEntry(const NamespaceString& nss, - const UUID& uuid, - const DbCheckCollectionInformation& expected, - const DbCheckCollectionInformation& found, - const repl::OpTime& optime) { - auto names = expectedFound(expected.collectionName, found.collectionName); - auto prevs = expectedFound(expected.prev, found.prev); - auto nexts = expectedFound(expected.next, found.next); - auto indices = expectedFound(expected.indexes, found.indexes); - auto options = expectedFound(expected.options, found.options); - bool match = names.first && prevs.first && nexts.first && indices.first && options.first; - auto severity = match ? SeverityEnum::Info : SeverityEnum::Error; - - // Get the hash of all of the other fields. - auto md5s = expectedFound(hashCollectionInfo(expected), hashCollectionInfo(found)); - - std::string msg = - "dbCheck collection " + (match ? std::string("consistent") : std::string("inconsistent")); - auto data = BSON("success" << true << "uuid" << uuid.toString() << "found" << true << "name" - << names.second << "prev" << prevs.second << "next" << nexts.second - << "indexes" << indices.second << "options" << options.second - << "md5" << md5s.second << "optime" << optime); - - return dbCheckHealthLogEntry(nss, severity, msg, OplogEntriesEnum::Collection, data); -} - Status DbCheckHasher::hashAll(void) { BSONObj currentObj; @@ -365,30 +294,6 @@ bool DbCheckHasher::_canHash(const BSONObj& obj) { return true; } -std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, Collection* collection) { - std::vector<BSONObj> result; - std::vector<std::string> names; - - // List the indices, - auto durableCatalog = DurableCatalog::get(opCtx); - durableCatalog->getAllIndexes(opCtx, collection->getCatalogId(), &names); - - // and get the info for each one. - for (const auto& name : names) { - result.push_back(durableCatalog->getIndexSpec(opCtx, collection->getCatalogId(), name)); - } - - auto comp = std::make_unique<SimpleBSONObjComparator>(); - - std::sort(result.begin(), result.end(), SimpleBSONObjComparator::LessThan()); - - return result; -} - -BSONObj collectionOptions(OperationContext* opCtx, Collection* collection) { - return BSON("doNotCare" << 1); -} - namespace { Status dbCheckBatchOnSecondary(OperationContext* opCtx, @@ -453,54 +358,6 @@ Status dbCheckBatchOnSecondary(OperationContext* opCtx, return Status::OK(); } -Status dbCheckDatabaseOnSecondary(OperationContext* opCtx, - const repl::OpTime& optime, - const DbCheckOplogCollection& entry) { - // dbCheckCollectionResult-specific stuff. - auto uuid = uassertStatusOK(UUID::parse(entry.getUuid().toString())); - auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, uuid); - - if (!collection) { - Status status(ErrorCodes::NamespaceNotFound, "Could not find collection for dbCheck"); - auto logEntry = dbCheckErrorHealthLogEntry( - entry.getNss(), "dbCheckCollection failed", OplogEntriesEnum::Collection, status); - HealthLog::get(opCtx).log(*logEntry); - return Status::OK(); - } - - auto db = collection->ns().db(); - AutoGetDb agd(opCtx, db, MODE_X); - - DbCheckCollectionInformation expected; - DbCheckCollectionInformation found; - - expected.collectionName = entry.getNss().coll().toString(); - found.collectionName = collection->ns().coll().toString(); - - auto prevAndNext = getPrevAndNextUUIDs(opCtx, collection); - - // found/expected previous UUID, - expected.prev = entry.getPrev(); - found.prev = prevAndNext.first; - - // found/expected next UUID, - expected.next = entry.getNext(); - found.next = prevAndNext.second; - - // found/expected indices, - expected.indexes = entry.getIndexes(); - found.indexes = collectionIndexInfo(opCtx, collection); - - // and found/expected collection options. - expected.options = entry.getOptions(); - found.options = collectionOptions(opCtx, collection); - - auto hle = dbCheckCollectionEntry(entry.getNss(), uuid, expected, found, optime); - - HealthLog::get(opCtx).log(*hle); - - return Status::OK(); -} } // namespace namespace repl { @@ -525,8 +382,8 @@ Status dbCheckOplogCommand(OperationContext* opCtx, return dbCheckBatchOnSecondary(opCtx, opTime, invocation); } case OplogEntriesEnum::Collection: { - auto invocation = DbCheckOplogCollection::parse(ctx, cmd); - return dbCheckDatabaseOnSecondary(opCtx, opTime, invocation); + // TODO SERVER-61963. + return Status::OK(); } } diff --git a/src/mongo/db/repl/dbcheck.h b/src/mongo/db/repl/dbcheck.h index 2722721a8ba..754b41e4ff3 100644 --- a/src/mongo/db/repl/dbcheck.h +++ b/src/mongo/db/repl/dbcheck.h @@ -79,33 +79,6 @@ std::unique_ptr<HealthLogEntry> dbCheckBatchEntry( const boost::optional<CollectionOptions>& options = boost::none); /** - * The collection metadata dbCheck sends between nodes. - */ -struct DbCheckCollectionInformation { - std::string collectionName; - boost::optional<UUID> prev; - boost::optional<UUID> next; - std::vector<BSONObj> indexes; - BSONObj options; -}; - -/** - * Returns a pair of previous and next UUIDs around the given collections uuid. If there is no - * previous or next UUID, return boost::none respectively. - */ -std::pair<boost::optional<UUID>, boost::optional<UUID>> getPrevAndNextUUIDs(OperationContext* opCtx, - Collection* collection); - -/** - * Get a HealthLogEntry for a dbCheck collection. - */ -std::unique_ptr<HealthLogEntry> dbCheckCollectionEntry(const NamespaceString& nss, - const UUID& uuid, - const DbCheckCollectionInformation& expected, - const DbCheckCollectionInformation& found, - const repl::OpTime& optime); - -/** * Hashing collections and plans. * * Provides MD5-based hashing of ranges of documents. Note that this class does *not* provide @@ -176,16 +149,6 @@ private: int64_t _bytesSeen = 0; }; -/** - * Gather the index information for a collection. - */ -std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, Collection* collection); - -/** - * Gather other information for a collection. - */ -BSONObj collectionOptions(OperationContext* opCtx, Collection* collection); - namespace repl { /** |