diff options
author | Matt Kneiser <matt.kneiser@mongodb.com> | 2022-09-29 04:14:06 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-09-29 05:17:36 +0000 |
commit | 1990f6a8a6cab84e2ddd05ab0469b9481b962ed5 (patch) | |
tree | 49361f6c55c71d6b01b9cec319d773dd21be2755 | |
parent | 1912e879e904b96a331cd2a2d20e7abf23684359 (diff) | |
download | mongo-1990f6a8a6cab84e2ddd05ab0469b9481b962ed5.tar.gz |
SERVER-69387 Debug Selectively Restored Sharded Collections
-rw-r--r-- | jstests/sharding/run_restore.js | 14 | ||||
-rw-r--r-- | jstests/sharding/run_restore_unsharded.js | 4 | ||||
-rw-r--r-- | src/mongo/db/s/config/configsvr_run_restore_command.cpp | 64 |
3 files changed, 68 insertions, 14 deletions
diff --git a/jstests/sharding/run_restore.js b/jstests/sharding/run_restore.js index 1d0a5dc821f..d16560f8725 100644 --- a/jstests/sharding/run_restore.js +++ b/jstests/sharding/run_restore.js @@ -116,8 +116,20 @@ assert.commandWorked(conn.getDB("admin").runCommand({setParameter: 1, logLevel: assert.commandFailedWithCode(conn.getDB("admin").runCommand({_configsvrRunRestore: 1}), ErrorCodes.NamespaceNotFound); -// Create the "local.system.collections_to_restore" collection and insert "test.a". +let [_, uuidStr] = aCollUUID.toString().match(/"((?:\\.|[^"\\])*)"/); +assert.commandWorked(conn.getDB("local").getCollection("system.collections_to_restore").insert({ + ns: "test.a", + uuid: uuidStr +})); + +// The "local.system.collections_to_restore" collection must have UUID as the correct type. +assert.commandFailedWithCode(conn.getDB("admin").runCommand({_configsvrRunRestore: 1}), + ErrorCodes.BadValue); + +// Recreate the "local.system.collections_to_restore" collection and insert 'test.a'. +assert(conn.getDB("local").getCollection("system.collections_to_restore").drop()); assert.commandWorked(conn.getDB("local").createCollection("system.collections_to_restore")); + assert.commandWorked(conn.getDB("local").getCollection("system.collections_to_restore").insert({ ns: "test.a", uuid: aCollUUID diff --git a/jstests/sharding/run_restore_unsharded.js b/jstests/sharding/run_restore_unsharded.js index e55377bfaa9..d9ad5d0edc9 100644 --- a/jstests/sharding/run_restore_unsharded.js +++ b/jstests/sharding/run_restore_unsharded.js @@ -11,8 +11,8 @@ load("jstests/libs/feature_flag_util.js"); -const s = - new ShardingTest({name: "runRestore", shards: 2, mongos: 1, config: 1, other: {chunkSize: 1}}); +const s = new ShardingTest( + {name: "runRestoreUnsharded", shards: 2, mongos: 1, config: 1, other: {chunkSize: 1}}); let mongos = s.s0; let db = s.getDB("test"); diff --git a/src/mongo/db/s/config/configsvr_run_restore_command.cpp b/src/mongo/db/s/config/configsvr_run_restore_command.cpp index 4790aefa1f8..ef9de4c5231 100644 --- a/src/mongo/db/s/config/configsvr_run_restore_command.cpp +++ b/src/mongo/db/s/config/configsvr_run_restore_command.cpp @@ -37,6 +37,8 @@ #include "mongo/db/repl/storage_interface_impl.h" #include "mongo/logv2/log.h" #include "mongo/stdx/unordered_map.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/uuid.h" #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kSharding @@ -71,8 +73,27 @@ ShouldRestoreDocument shouldRestoreDocument(OperationContext* opCtx, findRequest.setLimit(1); DBDirectClient client(opCtx); - return client.find(findRequest)->itcount() > 0 ? ShouldRestoreDocument::kYes - : ShouldRestoreDocument::kNo; + auto resultCount = client.find(findRequest)->itcount(); + + // Log in cases where the schema is not adhered to. + if (resultCount == 0 && uuid) { + auto schemaCheckFindRequest = + FindCommandRequest(NamespaceString::kConfigsvrRestoreNamespace); + auto collectionsToRestore = client.find(schemaCheckFindRequest); + while (collectionsToRestore->more()) { + auto doc = collectionsToRestore->next(); + try { + (void)UUID::parse(doc); + } catch (const AssertionException&) { + uasserted(ErrorCodes::BadValue, + str::stream() << "The uuid field of '" << doc.toString() << "' in '" + << NamespaceString::kConfigsvrRestoreNamespace.toString() + << "' needs to be of type UUID"); + } + } + } + + return resultCount > 0 ? ShouldRestoreDocument::kYes : ShouldRestoreDocument::kNo; } std::set<std::string> getDatabasesToRestore(OperationContext* opCtx) { @@ -164,12 +185,11 @@ public: restoreColl); } - // Keeps track of database names for collections restored. Databases with no collections - // restored will have their entries removed in the config collections. - std::set<std::string> databasesRestored = getDatabasesToRestore(opCtx); - for (const auto& collectionEntry : kCollectionEntries) { const NamespaceString& nss = collectionEntry.first; + boost::optional<std::string> nssFieldName = collectionEntry.second.first; + boost::optional<std::string> uuidFieldName = collectionEntry.second.second; + LOGV2(6261300, "1st Phase - Restoring collection entries", logAttrs(nss)); CollectionPtr coll = @@ -186,9 +206,6 @@ public: while (cursor->more()) { auto doc = cursor->next(); - boost::optional<std::string> nssFieldName = collectionEntry.second.first; - boost::optional<std::string> uuidFieldName = collectionEntry.second.second; - boost::optional<NamespaceString> docNss = boost::none; boost::optional<UUID> docUUID = boost::none; @@ -210,6 +227,11 @@ public: uassertStatusOK(swDocUUID); docUUID = swDocUUID.getValue(); + LOGV2_DEBUG(6938701, + 1, + "uuid found", + "uuid"_attr = uuidFieldName, + "docUUID"_attr = docUUID); } ShouldRestoreDocument shouldRestore = shouldRestoreDocument(opCtx, docNss, docUUID); @@ -218,7 +240,9 @@ public: 1, "Found document", "doc"_attr = doc, - "shouldRestore"_attr = shouldRestore); + "shouldRestore"_attr = shouldRestore, + "db"_attr = coll->ns().db().toString(), + "docNss"_attr = docNss); if (shouldRestore == ShouldRestoreDocument::kYes || shouldRestore == ShouldRestoreDocument::kMaybe) { @@ -226,12 +250,22 @@ public: } // The collection for this document was not restored, delete it. + LOGV2_DEBUG(6938702, + 1, + "Deleting collection that was not restored", + "db"_attr = coll->ns().db().toString(), + "uuid"_attr = coll->uuid(), + "_id"_attr = doc.getField("_id")); NamespaceStringOrUUID nssOrUUID(coll->ns().db().toString(), coll->uuid()); uassertStatusOK(repl::StorageInterface::get(opCtx)->deleteById( opCtx, nssOrUUID, doc.getField("_id"))); } } + // Keeps track of database names for collections restored. Databases with no collections + // restored will have their entries removed in the config collections. + std::set<std::string> databasesRestored = getDatabasesToRestore(opCtx); + { const std::vector<NamespaceString> databasesEntries = { NamespaceString("config.databases")}; @@ -267,7 +301,9 @@ public: 1, "Found document", "doc"_attr = doc, - "shouldRestore"_attr = shouldRestore); + "shouldRestore"_attr = shouldRestore, + "db"_attr = coll->ns().db().toString(), + "dbNss"_attr = dbNss.toString()); if (shouldRestore) { // This database had at least one collection restored. @@ -275,6 +311,12 @@ public: } // No collection for this database was restored, delete it. + LOGV2_DEBUG(6938703, + 1, + "Deleting database that was not restored", + "db"_attr = coll->ns().db().toString(), + "uuid"_attr = coll->uuid(), + "_id"_attr = doc.getField("_id")); NamespaceStringOrUUID nssOrUUID(coll->ns().db().toString(), coll->uuid()); uassertStatusOK(repl::StorageInterface::get(opCtx)->deleteById( opCtx, nssOrUUID, doc.getField("_id"))); |