diff options
author | Benety Goh <benety@mongodb.com> | 2018-09-10 10:48:52 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2018-09-10 10:48:52 -0400 |
commit | 8f37bba5a81b975101ae0ad4a0f894cce6dba648 (patch) | |
tree | 8192f61ec58feae8c8c7cbbf8b6a07648847b40d /src/mongo | |
parent | 660fb03fe223cacc1c35d3c0e7b266ab5679f31d (diff) | |
download | mongo-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.cpp | 45 |
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); |