diff options
author | Louis Williams <louis.williams@mongodb.com> | 2020-06-03 10:20:39 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-06-03 18:27:40 +0000 |
commit | f9df74846d8fd8e9c9530d0b53df4a222c255378 (patch) | |
tree | c7db31ad9f8d404d55699d975c00216f2267d9cc | |
parent | 673c659b0ae6a66e6da1ce87dda1597df18067e7 (diff) | |
download | mongo-f9df74846d8fd8e9c9530d0b53df4a222c255378.tar.gz |
SERVER-48549 createIndexes must not access collection outside of lock
(cherry picked from commit eab3da634bc745c25c7dd38c07e4911e81020e04)
-rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 20 |
1 files changed, 7 insertions, 13 deletions
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index 4c3944b1255..0b8206aa661 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -355,22 +355,12 @@ void fillCommandResultWithIndexesAlreadyExistInfo(int numIndexes, BSONObjBuilder }; /** - * Before potentially taking an exclusive database or collection lock, check if all indexes - * already exist while holding an intent lock. - * * Returns true, after filling in the command result, if the index creation can return early. */ bool indexesAlreadyExist(OperationContext* opCtx, - const NamespaceString& ns, + const Collection* collection, const std::vector<BSONObj>& specs, BSONObjBuilder* result) { - AutoGetCollection autoColl(opCtx, ns, MODE_IX); - - auto collection = autoColl.getCollection(); - if (!collection) { - return false; - } - auto specsCopy = resolveDefaultsAndRemoveExistingIndexes(opCtx, collection, specs); if (specsCopy.size() > 0) { return false; @@ -536,11 +526,15 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx, } bool indexExists = writeConflictRetry(opCtx, "createCollectionWithIndexes", ns.ns(), [&] { - if (indexesAlreadyExist(opCtx, ns, specs, &result)) { + AutoGetCollection autoColl(opCtx, ns, MODE_IX); + auto collection = autoColl.getCollection(); + + // Before potentially taking an exclusive collection lock, check if all indexes already + // exist while holding an intent lock. + if (collection && indexesAlreadyExist(opCtx, collection, specs, &result)) { return true; } - auto collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, ns); if (collection && !UncommittedCollections::get(opCtx).isUncommittedCollection(opCtx, ns)) { // The collection exists and was not created in the same multi-document transaction |