summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2019-08-16 11:19:33 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-19 16:14:46 +0000
commit8c619ff1f0eb7c2a7ac228354ba6aa79e89e21d4 (patch)
tree08c1be4c2318c3ca9e2a8a22de2e71e03227656c
parent4e974c48b158e4644d7f0c27354e67c4409db460 (diff)
downloadmongo-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.cpp105
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,