summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosef Ahmad <josef.ahmad@mongodb.com>2021-12-14 10:00:38 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-16 08:55:27 +0000
commit1c5cf91ebff1a81a43be37ece3d5f5003bac81e7 (patch)
treedb8d62930404b1205954dc1cc2c2163e99b69852
parentd1f74cceb696a33b2486b04e569152de4922b2de (diff)
downloadmongo-1c5cf91ebff1a81a43be37ece3d5f5003bac81e7.tar.gz
SERVER-61877 Remove catalog consistency verification from dbCheck
(cherry picked from commit a7769499d4f46deb5c52cacad15c499a70e42683)
-rw-r--r--jstests/replsets/dbcheck.js36
-rw-r--r--src/mongo/db/commands/dbcheck.cpp66
-rw-r--r--src/mongo/db/repl/dbcheck.cpp146
-rw-r--r--src/mongo/db/repl/dbcheck.h37
4 files changed, 4 insertions, 281 deletions
diff --git a/jstests/replsets/dbcheck.js b/jstests/replsets/dbcheck.js
index d0c072a6f03..147c6a736f6 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 b4f70102c8e..0ebf4fcc013 100644
--- a/src/mongo/db/commands/dbcheck.cpp
+++ b/src/mongo/db/commands/dbcheck.cpp
@@ -188,10 +188,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;
@@ -286,66 +284,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 21bade8c0a1..58baed702e4 100644
--- a/src/mongo/db/repl/dbcheck.cpp
+++ b/src/mongo/db/repl/dbcheck.cpp
@@ -225,77 +225,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, const CollectionPtr& collection) {
- auto 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;
@@ -364,29 +293,6 @@ bool DbCheckHasher::_canHash(const BSONObj& obj) {
return true;
}
-std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const CollectionPtr& collection) {
- std::vector<BSONObj> result;
- std::vector<std::string> names;
-
- // List the indices,
- collection->getAllIndexes(&names);
-
- // and get the info for each one.
- for (const auto& name : names) {
- result.push_back(collection->getIndexSpec(name));
- }
-
- auto comp = std::make_unique<SimpleBSONObjComparator>();
-
- std::sort(result.begin(), result.end(), SimpleBSONObjComparator::LessThan());
-
- return result;
-}
-
-BSONObj collectionOptions(OperationContext* opCtx, const CollectionPtr& collection) {
- return collection->getCollectionOptions().toBSON();
-}
-
namespace {
Status dbCheckBatchOnSecondary(OperationContext* opCtx,
@@ -451,54 +357,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 {
@@ -523,8 +381,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 0d8706319b0..6dac7630bd7 100644
--- a/src/mongo/db/repl/dbcheck.h
+++ b/src/mongo/db/repl/dbcheck.h
@@ -80,33 +80,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, const CollectionPtr& 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
@@ -177,16 +150,6 @@ private:
int64_t _bytesSeen = 0;
};
-/**
- * Gather the index information for a collection.
- */
-std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const CollectionPtr& collection);
-
-/**
- * Gather other information for a collection.
- */
-BSONObj collectionOptions(OperationContext* opCtx, const CollectionPtr& collection);
-
namespace repl {
/**