summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2018-09-10 10:48:52 -0400
committerBenety Goh <benety@mongodb.com>2018-09-10 10:48:52 -0400
commit8f37bba5a81b975101ae0ad4a0f894cce6dba648 (patch)
tree8192f61ec58feae8c8c7cbbf8b6a07648847b40d /src/mongo
parent660fb03fe223cacc1c35d3c0e7b266ab5679f31d (diff)
downloadmongo-8f37bba5a81b975101ae0ad4a0f894cce6dba648.tar.gz
SERVER-37002 collection rename drops indexes with long names in the target namespace
This is already done implicitly during a two phase collection drop. Renaming a collection with dropTarget set to true should handle long index names in a similar manner.
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/catalog/rename_collection.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp
index 7787aead9ab..45053d05d67 100644
--- a/src/mongo/db/catalog/rename_collection.cpp
+++ b/src/mongo/db/catalog/rename_collection.cpp
@@ -275,6 +275,51 @@ Status renameCollectionCommon(OperationContext* opCtx,
invariant(options.dropTarget);
auto dropTargetUUID = targetColl->uuid();
invariant(dropTargetUUID);
+
+ // 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);
+ if (!isOplogDisabledForNamespace) {
+ 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.";
+ fassert(50941, targetColl->getIndexCatalog()->dropIndex(opCtx, index));
+ opObserver->onDropIndex(
+ opCtx, target, targetColl->uuid(), index->indexName(), index->infoObj());
+ }
+ }
+
auto renameOpTime = opObserver->preRenameCollection(
opCtx, source, target, sourceUUID, dropTargetUUID, options.stayTemp);