diff options
author | Benety Goh <benety@mongodb.com> | 2018-09-10 10:48:52 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2018-09-10 11:44:07 -0400 |
commit | 6bc9ed599c3fa164703346a22bad17e33fa913e4 (patch) | |
tree | 29c067ca5ab6bc90bf423dbf56a0cef4ab4b104f /src/mongo/db | |
parent | 55c7f626633ebbdad42938a975c015729d40d0b9 (diff) | |
download | mongo-r3.6.8-rc1.tar.gz |
SERVER-37002 collection rename drops indexes with long names in the target namespacer3.6.8-rc1r3.6.8
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.
(cherry picked from commit 8f37bba5a81b975101ae0ad4a0f894cce6dba648)
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/catalog/rename_collection.cpp | 47 |
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); |