SERVER-112943 Error message to include missing index names when collection is not empty (#44950)

GitOrigin-RevId: 4e7fe2a2f0d87c11fe5bd74eba25cc5c3ce25cad
This commit is contained in:
Adi Zaimi 2025-12-15 09:59:30 -05:00 committed by MongoDB Bot
parent 5111a71a19
commit 5f14e53429
2 changed files with 55 additions and 6 deletions

View File

@ -1205,12 +1205,17 @@ void _cloneCollectionIndexesAndOptions(
opCtx, collection, collectionOptionsAndIndexes.indexSpecs, opts);
if (!indexSpecs.empty()) {
// Only allow indexes to be copied if the collection does not have any documents.
uassert(ErrorCodes::CannotCreateCollection,
str::stream() << "aborting, shard is missing " << indexSpecs.size()
<< " indexes and "
<< "collection is not empty. Non-trivial "
<< "index creation should be scheduled manually",
collection->isEmpty(opCtx));
std::string errMsg = "aborting, shard is missing " + std::to_string(indexSpecs.size()) +
" indexes and collection is not empty. Non-trivial " +
"index creation should be scheduled manually. Missing indexes:";
std::string separator = " ";
for (const auto& spec : indexSpecs) {
if (spec.hasField("name")) {
errMsg += separator + std::string{spec.getStringField("name")};
separator = ", ";
}
}
uassert(ErrorCodes::CannotCreateCollection, errMsg, collection->isEmpty(opCtx));
// If synchronizing indexes strictly, mark waitForInProgressIndexBuildCompletion as
// true to wait for index builds to be finished after releasing the locks.

View File

@ -34,6 +34,7 @@
#include "mongo/base/error_codes.h"
#include "mongo/bson/bsonelement.h"
#include "mongo/bson/bsonmisc.h"
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/index/index_constants.h"
#include "mongo/db/router_role/routing_cache/catalog_cache_test_fixture.h"
#include "mongo/db/s/migration_destination_manager.h"
@ -47,6 +48,8 @@
#include <system_error>
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kTest
namespace mongo {
namespace {
@ -242,5 +245,46 @@ TEST_F(MigrationDestinationManagerNetworkTest,
future.default_timed_get();
}
// Tests that error message includes missing index names when collection is not empty.
TEST_F(MigrationDestinationManagerTest, ErrorMessageIncludesMissingIndexNames) {
const NamespaceString nss = NamespaceString::createNamespaceString_forTest("test.foo");
boost::optional<UUID> collectionUUID;
auto opCtx = operationContext();
DBDirectClient client(opCtx);
// Create a collection with some data (so it's not empty).
// Note that index on '_id' is built by default.
client.insert(nss, BSON("_id" << 1 << "x" << 1));
// Get the UUID of the created collection directly from the catalog.
auto catalog = CollectionCatalog::get(opCtx);
auto uuid = catalog->lookupUUIDByNSS(opCtx, nss);
ASSERT_TRUE(uuid);
collectionUUID.emplace(*uuid);
// Prepare index specs that include indexes not on the local collection.
// Use the actual UUID of the created collection.
ASSERT(collectionUUID.has_value());
CollectionOptionsAndIndexes collectionOptionsAndIndexes{
*collectionUUID,
{
BSON("v" << 2 << "key" << BSON("y" << 1) << "name" << "y_1"), // Missing index
BSON("v" << 2 << "key" << BSON("z" << 1) << "name" << "z_1") // Missing index
},
BSON("v" << 2 << "key" << BSON("_id" << 1) << "name" << IndexConstants::kIdIndexName),
BSONObj()};
LOGV2(11294300, "The error message should list the missing index names: y_1 and z_1.");
ASSERT_THROWS_CODE_AND_WHAT(
MigrationDestinationManager::cloneCollectionIndexesAndOptions(
operationContext(), nss, collectionOptionsAndIndexes),
DBException,
ErrorCodes::CannotCreateCollection,
"aborting, shard is missing 2 indexes and collection is not empty. Non-trivial index "
"creation should be scheduled manually. Missing indexes: y_1, z_1");
}
} // namespace
} // namespace mongo