summaryrefslogtreecommitdiff
path: root/src/mongo/db/cloner.cpp
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2019-11-26 04:48:50 +0000
committerevergreen <evergreen@mongodb.com>2019-11-26 04:48:50 +0000
commitd471957fc37ef6cafe9ffeda3e231cdc871c3ce3 (patch)
tree3435c9d9420243e350da0f3dfbeecb81afbcd264 /src/mongo/db/cloner.cpp
parent8b0f534a706005d366e200ee56af5c76217656b2 (diff)
downloadmongo-d471957fc37ef6cafe9ffeda3e231cdc871c3ce3.tar.gz
SERVER-43859: Take MODE_IX locks for collection creation.
Two concurrent storage transactions can now create collections with the same collection name. These transactions will conflict at commit time; the first committer will win and register their collection into the global catalog. The losing transactions will bubble a WriteConflictException. Top-level callers that should fail if the collection already existed must now check and fail with a NamespaceExists error code. Previously, those callers could rely on lower level code returning the NamespaceExists error. Callers that were implicitly creating a collection may retry the operation, using the now-registered collection. These transaction-local collections (UncommittedCollections) are returned when doing any CollectionCatalog::lookup* call.
Diffstat (limited to 'src/mongo/db/cloner.cpp')
-rw-r--r--src/mongo/db/cloner.cpp15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index c6475cbe0e9..410def3bffa 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -117,7 +117,8 @@ struct Cloner::Fun {
bool createdCollection = false;
Collection* collection = nullptr;
- collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(to_collection);
+ collection =
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, to_collection);
if (!collection) {
massert(17321,
str::stream() << "collection dropped during clone [" << to_collection.ns()
@@ -139,7 +140,7 @@ struct Cloner::Fun {
<< to_collection.ns() << "]");
wunit.commit();
collection =
- CollectionCatalog::get(opCtx).lookupCollectionByNamespace(to_collection);
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, to_collection);
invariant(collection,
str::stream()
<< "Missing collection during clone [" << to_collection.ns() << "]");
@@ -181,7 +182,7 @@ struct Cloner::Fun {
db != nullptr);
collection =
- CollectionCatalog::get(opCtx).lookupCollectionByNamespace(to_collection);
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, to_collection);
uassert(28594,
str::stream()
<< "Collection " << to_collection.ns() << " dropped while cloning",
@@ -329,7 +330,7 @@ void Cloner::copyIndexes(OperationContext* opCtx,
auto db = databaseHolder->openDb(opCtx, toDBName);
Collection* collection =
- CollectionCatalog::get(opCtx).lookupCollectionByNamespace(to_collection);
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, to_collection);
if (!collection) {
writeConflictRetry(opCtx, "createCollection", to_collection.ns(), [&] {
opCtx->checkForInterrupt();
@@ -347,7 +348,8 @@ void Cloner::copyIndexes(OperationContext* opCtx,
<< "Collection creation failed while copying indexes from "
<< from_collection.ns() << " to " << to_collection.ns() << " (Cloner)");
wunit.commit();
- collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(to_collection);
+ collection =
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, to_collection);
invariant(collection,
str::stream() << "Missing collection " << to_collection.ns() << " (Cloner)");
});
@@ -586,7 +588,8 @@ Status Cloner::createCollectionsForDb(
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
- Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(nss);
+ Collection* collection =
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
if (collection) {
if (!params.shardedColl) {
// If the collection is unsharded then we want to fail when a collection