summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/rename_collection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/rename_collection.cpp')
-rw-r--r--src/mongo/db/catalog/rename_collection.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp
index 9ef84923199..af4f6970285 100644
--- a/src/mongo/db/catalog/rename_collection.cpp
+++ b/src/mongo/db/catalog/rename_collection.cpp
@@ -254,6 +254,53 @@ Status renameCollectionCommon(OperationContext* opCtx,
// Target collection exists - drop it.
invariant(options.dropTarget);
auto dropTargetUUID = targetColl->uuid();
+
+ // If this rename collection is replicated, check for long index names in the target
+ // collection that may exceed the MMAPv1 namespace limit when the target collection
+ // is renamed with a drop-pending namespace.
+ auto replCoord = repl::ReplicationCoordinator::get(opCtx);
+ auto isOplogDisabledForNamespace = replCoord->isOplogDisabledFor(opCtx, target);
+ auto isMasterSlave =
+ repl::ReplicationCoordinator::modeMasterSlave == replCoord->getReplicationMode();
+ if (!isOplogDisabledForNamespace && !isMasterSlave) {
+ invariant(opCtx->writesAreReplicated());
+ invariant(renameOpTimeFromApplyOps.isNull());
+
+ // Compile a list of any indexes that would become too long following the
+ // drop-pending rename. In the case that this collection drop gets rolled back, this
+ // will incur a performance hit, since those indexes will have to be rebuilt from
+ // scratch, but data integrity is maintained.
+ std::vector<IndexDescriptor*> indexesToDrop;
+ auto indexIter = targetColl->getIndexCatalog()->getIndexIterator(opCtx, true);
+
+ // Determine which index names are too long. Since we don't have the collection
+ // rename optime at this time, use the maximum optime to check the index names.
+ auto longDpns = target.makeDropPendingNamespace(repl::OpTime::max());
+ while (indexIter.more()) {
+ auto index = indexIter.next();
+ auto status = longDpns.checkLengthForRename(index->indexName().size());
+ if (!status.isOK()) {
+ indexesToDrop.push_back(index);
+ }
+ }
+
+ // Drop the offending indexes.
+ auto sourceUuidString = sourceUUID ? sourceUUID.get().toString() : "no UUID";
+ auto dropTargetUuidString =
+ dropTargetUUID ? dropTargetUUID.get().toString() : "no UUID";
+ for (auto&& index : indexesToDrop) {
+ log() << "renameCollection: renaming collection " << sourceUuidString
+ << " from " << source << " to " << target << " (" << dropTargetUuidString
+ << ") - target collection contains an index namespace '"
+ << index->indexNamespace()
+ << "' that would be too long after drop-pending rename. Dropping index "
+ "immediately.";
+ fassertStatusOK(50941, targetColl->getIndexCatalog()->dropIndex(opCtx, index));
+ opObserver->onDropIndex(
+ opCtx, target, targetColl->uuid(), index->indexName(), index->infoObj());
+ }
+ }
+
auto renameOpTime = opObserver->onRenameCollection(
opCtx, source, target, sourceUUID, true, dropTargetUUID, options.stayTemp);