diff options
author | Benety Goh <benety@mongodb.com> | 2018-12-21 16:43:10 -0500 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2019-03-09 07:45:00 -0500 |
commit | fcd6b96dd47cfbb295e280d9bd4a7ef71f7305be (patch) | |
tree | 048358301088e86ba2f51de3a5ecfbcc94cbe28c | |
parent | 023d3450d39c62a3cc70f6cdc4a52a7f486aeb37 (diff) | |
download | mongo-fcd6b96dd47cfbb295e280d9bd4a7ef71f7305be.tar.gz |
SERVER-38745 convert MigrationDestinationManager::cloneCollectionIndexesAndOptions() to use IndexCatalog::createIndexOnEmptyCollection()
(cherry picked from commit 7b85fb049b087fbcb04d6f356a0f7bee9ef48190)
-rw-r--r-- | src/mongo/db/s/migration_destination_manager.cpp | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp index 2233daf726f..09be6aefbf2 100644 --- a/src/mongo/db/s/migration_destination_manager.cpp +++ b/src/mongo/db/s/migration_destination_manager.cpp @@ -635,36 +635,45 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationCont collection = db->getCollection(opCtx, nss); } - MultiIndexBlock indexer(opCtx, collection); - indexer.removeExistingIndexes(&donorIndexSpecs); - - if (!donorIndexSpecs.empty()) { - // Only copy indexes if the collection does not have any documents. - uassert(ErrorCodes::CannotCreateCollection, - str::stream() << "aborting, shard is missing " << donorIndexSpecs.size() - << " indexes and " - << "collection is not empty. Non-trivial " - << "index creation should be scheduled manually", - collection->numRecords(opCtx) == 0); - - auto indexInfoObjs = indexer.init(donorIndexSpecs); - uassert(ErrorCodes::CannotCreateIndex, - str::stream() << "failed to create index before migrating data. " - << " error: " - << redact(indexInfoObjs.getStatus()), - indexInfoObjs.isOK()); - - WriteUnitOfWork wunit(opCtx); - indexer.commit(); - - for (auto&& infoObj : indexInfoObjs.getValue()) { - // make sure to create index on secondaries as well - serviceContext->getOpObserver()->onCreateIndex( - opCtx, collection->ns(), collection->uuid(), infoObj, true /* fromMigrate */); - } - wunit.commit(); + auto indexCatalog = collection->getIndexCatalog(); + { + // Use MultiIndexBlock to filter existing indexes but not to build indexes. + MultiIndexBlock indexer(opCtx, collection); + indexer.removeExistingIndexes(&donorIndexSpecs); + indexer.abortWithoutCleanup(); + } + const auto& indexSpecs = donorIndexSpecs; + + if (indexSpecs.empty()) { + return; } + + // Only copy indexes if the collection does not have any documents. + uassert(ErrorCodes::CannotCreateCollection, + str::stream() << "aborting, shard is missing " << indexSpecs.size() + << " indexes and " + << "collection is not empty. Non-trivial " + << "index creation should be scheduled manually", + collection->numRecords(opCtx) == 0); + + WriteUnitOfWork wunit(opCtx); + + for (const auto& spec : indexSpecs) { + // Make sure to create index on secondaries as well. Oplog entry must be written before + // the index is added to the index catalog for correct rollback operation. + // See SERVER-35780 and SERVER-35070. + serviceContext->getOpObserver()->onCreateIndex( + opCtx, collection->ns(), *(collection->uuid()), spec, true /* fromMigrate */); + + // Since the collection is empty, we can add and commit the index catalog entry within + // a single WUOW. + uassertStatusOKWithContext( + indexCatalog->createIndexOnEmptyCollection(opCtx, spec), + str::stream() << "failed to create index before migrating data: " << redact(spec)); + } + + wunit.commit(); } } |