diff options
author | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2019-08-16 11:19:33 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-02-19 16:14:46 +0000 |
commit | 8c619ff1f0eb7c2a7ac228354ba6aa79e89e21d4 (patch) | |
tree | 08c1be4c2318c3ca9e2a8a22de2e71e03227656c | |
parent | 4e974c48b158e4644d7f0c27354e67c4409db460 (diff) | |
download | mongo-8c619ff1f0eb7c2a7ac228354ba6aa79e89e21d4.tar.gz |
SERVER-42830: Wrap all of renameCollectionWithinDBForApplyOps into one WUOW.
(cherry picked from commit 10dd7ef95fab6b869818f54827d4e03924846432)
-rw-r--r-- | src/mongo/db/catalog/rename_collection.cpp | 105 |
1 files changed, 59 insertions, 46 deletions
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp index 1d5538ec58d..44c3b57ec9e 100644 --- a/src/mongo/db/catalog/rename_collection.cpp +++ b/src/mongo/db/catalog/rename_collection.cpp @@ -389,7 +389,6 @@ Status renameCollectionWithinDBForApplyOps(OperationContext* opCtx, auto db = DatabaseHolder::get(opCtx)->getDb(opCtx, source.db()); Collection* const sourceColl = db->getCollection(opCtx, source); - Collection* targetColl = db->getCollection(opCtx, target); AutoStatsTracker statsTracker(opCtx, source, @@ -397,66 +396,80 @@ Status renameCollectionWithinDBForApplyOps(OperationContext* opCtx, AutoStatsTracker::LogMode::kUpdateCurOp, db->getProfilingLevel()); - if (targetColl) { - if (sourceColl->uuid() == targetColl->uuid()) { - if (!uuidToDrop || uuidToDrop == targetColl->uuid()) { - return Status::OK(); - } + return writeConflictRetry(opCtx, "renameCollection", target.ns(), [&] { + Collection* targetColl = db->getCollection(opCtx, target); + WriteUnitOfWork wuow(opCtx); + if (targetColl) { + if (sourceColl->uuid() == targetColl->uuid()) { + if (!uuidToDrop || uuidToDrop == targetColl->uuid()) { + wuow.commit(); + return Status::OK(); + } - // During initial sync, it is possible that the collection already - // got renamed to the target, so there is not much left to do other - // than drop the dropTarget. See SERVER-40861 for more details. - return writeConflictRetry(opCtx, "renameCollection", target.ns(), [&] { - WriteUnitOfWork wunit(opCtx); + // During initial sync, it is possible that the collection already + // got renamed to the target, so there is not much left to do other + // than drop the dropTarget. See SERVER-40861 for more details. auto collToDropBasedOnUUID = getNamespaceFromUUID(opCtx, *uuidToDrop); - if (!collToDropBasedOnUUID) + if (!collToDropBasedOnUUID) { + wuow.commit(); return Status::OK(); + } repl::UnreplicatedWritesBlock uwb(opCtx); Status status = db->dropCollection(opCtx, *collToDropBasedOnUUID, renameOpTimeFromApplyOps); if (!status.isOK()) return status; - wunit.commit(); + wuow.commit(); return Status::OK(); - }); + } + + if (!uuidToDrop || uuidToDrop != targetColl->uuid()) { + // We need to rename the targetColl to a temporary name. + auto status = renameTargetCollectionToTmp( + opCtx, source, sourceColl->uuid().get(), db, target, targetColl->uuid().get()); + if (!status.isOK()) + return status; + targetColl = nullptr; + } } - if (!uuidToDrop || (uuidToDrop && uuidToDrop != targetColl->uuid())) { - // We need to rename the targetColl to a temporary name. - auto status = renameTargetCollectionToTmp( - opCtx, source, sourceColl->uuid().get(), db, target, targetColl->uuid().get()); - if (!status.isOK()) - return status; - targetColl = nullptr; + + // When reapplying oplog entries (such as in the case of initial sync) we need + // to identify the collection to drop by UUID, as otherwise we might end up + // dropping the wrong collection. + if (!targetColl && uuidToDrop) { + invariant(options.dropTarget); + auto collToDropBasedOnUUID = getNamespaceFromUUID(opCtx, uuidToDrop.get()); + if (collToDropBasedOnUUID && !collToDropBasedOnUUID->isDropPendingNamespace()) { + invariant(collToDropBasedOnUUID->db() == target.db()); + targetColl = db->getCollection(opCtx, *collToDropBasedOnUUID); + } } - } - // When reapplying oplog entries (such as in the case of initial sync) we need - // to identify the collection to drop by UUID, as otherwise we might end up - // dropping the wrong collection. - if (!targetColl && uuidToDrop) { - invariant(options.dropTarget); - auto collToDropBasedOnUUID = getNamespaceFromUUID(opCtx, uuidToDrop.get()); - if (collToDropBasedOnUUID && !collToDropBasedOnUUID->isDropPendingNamespace()) { - invariant(collToDropBasedOnUUID->db() == target.db()); - targetColl = db->getCollection(opCtx, *collToDropBasedOnUUID); + Status ret = Status::OK(); + if (!targetColl) { + ret = renameCollectionDirectly(opCtx, db, sourceColl->uuid(), source, target, options); + } else { + if (sourceColl == targetColl) { + wuow.commit(); + return Status::OK(); + } + + ret = renameCollectionAndDropTarget(opCtx, + db, + sourceColl->uuid(), + source, + target, + targetColl, + options, + renameOpTimeFromApplyOps); } - } - if (!targetColl) { - return renameCollectionDirectly(opCtx, db, sourceColl->uuid(), source, target, options); - } else { - if (sourceColl == targetColl) - return Status::OK(); + if (ret.isOK()) { + wuow.commit(); + } - return renameCollectionAndDropTarget(opCtx, - db, - sourceColl->uuid(), - source, - target, - targetColl, - options, - renameOpTimeFromApplyOps); - } + return ret; + }); } Status renameBetweenDBs(OperationContext* opCtx, |