diff options
author | Gregory Wlodarek <gregory.wlodarek@mongodb.com> | 2019-12-20 21:20:38 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-12-20 21:20:38 +0000 |
commit | 0e079cef6ba967a3cc930c6fb7960a9125a387ad (patch) | |
tree | a57b047678d5035061f82ee0f3e819ec7a17e7f5 /src/mongo/db | |
parent | c4d21d70c7ae90d1ef8635ff81cfc58d8926c770 (diff) | |
download | mongo-0e079cef6ba967a3cc930c6fb7960a9125a387ad.tar.gz |
SERVER-39596 While a node is not in primary/secondary state, dbStats/collStats should not hang
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/repl/collection_bulk_loader_impl.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.cpp | 25 |
2 files changed, 37 insertions, 11 deletions
diff --git a/src/mongo/db/repl/collection_bulk_loader_impl.cpp b/src/mongo/db/repl/collection_bulk_loader_impl.cpp index 944776aee8f..73d5c296cbf 100644 --- a/src/mongo/db/repl/collection_bulk_loader_impl.cpp +++ b/src/mongo/db/repl/collection_bulk_loader_impl.cpp @@ -227,6 +227,13 @@ Status CollectionBulkLoaderImpl::commit() { // constraints causing them to not be recorded. invariant(_secondaryIndexesBlock->checkConstraints(_opCtx.get())); + // Need to upgrade the collection lock to MODE_X to commit the index build. + if (!_opCtx->lockState()->isCollectionLockedForMode(_nss, MODE_X)) { + _autoColl = std::make_unique<AutoGetCollection>(_opCtx.get(), _nss, MODE_X); + _collection = _autoColl->getCollection(); + invariant(_collection); + } + status = writeConflictRetry( _opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns(), [this] { WriteUnitOfWork wunit(_opCtx.get()); @@ -288,6 +295,13 @@ Status CollectionBulkLoaderImpl::commit() { return status; } + // Need to upgrade the collection lock to MODE_X to commit the index build. + if (!_opCtx->lockState()->isCollectionLockedForMode(_nss, MODE_X)) { + _autoColl = std::make_unique<AutoGetCollection>(_opCtx.get(), _nss, MODE_X); + _collection = _autoColl->getCollection(); + invariant(_collection); + } + // Commit the _id index, there won't be any documents with duplicate _ids as they were // deleted prior to this. status = writeConflictRetry( @@ -318,6 +332,15 @@ Status CollectionBulkLoaderImpl::commit() { void CollectionBulkLoaderImpl::_releaseResources() { invariant(&cc() == _opCtx->getClient()); + + // Need to upgrade the collection lock to MODE_X to clean up the index build. + if (!_opCtx->lockState()->isCollectionLockedForMode(_nss, MODE_X) && + (_secondaryIndexesBlock || _idIndexBlock)) { + _autoColl = std::make_unique<AutoGetCollection>(_opCtx.get(), _nss, MODE_X); + _collection = _autoColl->getCollection(); + invariant(_collection); + } + if (_secondaryIndexesBlock) { _secondaryIndexesBlock->cleanUpAfterBuild( _opCtx.get(), _collection, MultiIndexBlock::kNoopOnCleanUpFn); diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index 17af180cd45..531e10afaad 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -217,28 +217,29 @@ StorageInterfaceImpl::createCollectionForBulkLoading( documentValidationDisabled(opCtx.get()) = true; - std::unique_ptr<AutoGetCollection> autoColl; // Retry if WCE. Status status = writeConflictRetry(opCtx.get(), "beginCollectionClone", nss.ns(), [&] { UnreplicatedWritesBlock uwb(opCtx.get()); // Get locks and create the collection. - AutoGetOrCreateDb db(opCtx.get(), nss.db(), MODE_IX); - AutoGetCollection coll(opCtx.get(), nss, fixLockModeForSystemDotViewsChanges(nss, MODE_X)); + AutoGetOrCreateDb autoDb(opCtx.get(), nss.db(), MODE_IX); + AutoGetCollection autoColl( + opCtx.get(), nss, fixLockModeForSystemDotViewsChanges(nss, MODE_X)); - if (coll.getCollection()) { + if (autoColl.getCollection()) { return Status(ErrorCodes::NamespaceExists, str::stream() << "Collection " << nss.ns() << " already exists."); } { // Create the collection. WriteUnitOfWork wunit(opCtx.get()); - fassert(40332, db.getDb()->createCollection(opCtx.get(), nss, options, false)); + fassert(40332, autoDb.getDb()->createCollection(opCtx.get(), nss, options, false)); wunit.commit(); } - autoColl = std::make_unique<AutoGetCollection>( - opCtx.get(), nss, fixLockModeForSystemDotViewsChanges(nss, MODE_IX)); + Collection* coll = + CollectionCatalog::get(opCtx.get()).lookupCollectionByNamespace(opCtx.get(), nss); + invariant(coll); // Build empty capped indexes. Capped indexes cannot be built by the MultiIndexBlock // because the cap might delete documents off the back while we are inserting them into @@ -247,16 +248,14 @@ StorageInterfaceImpl::createCollectionForBulkLoading( WriteUnitOfWork wunit(opCtx.get()); if (!idIndexSpec.isEmpty()) { auto status = - autoColl->getCollection()->getIndexCatalog()->createIndexOnEmptyCollection( - opCtx.get(), idIndexSpec); + coll->getIndexCatalog()->createIndexOnEmptyCollection(opCtx.get(), idIndexSpec); if (!status.getStatus().isOK()) { return status.getStatus(); } } for (auto&& spec : secondaryIndexSpecs) { auto status = - autoColl->getCollection()->getIndexCatalog()->createIndexOnEmptyCollection( - opCtx.get(), spec); + coll->getIndexCatalog()->createIndexOnEmptyCollection(opCtx.get(), spec); if (!status.getStatus().isOK()) { return status.getStatus(); } @@ -271,6 +270,10 @@ StorageInterfaceImpl::createCollectionForBulkLoading( return status; } + std::unique_ptr<AutoGetCollection> autoColl = std::make_unique<AutoGetCollection>( + opCtx.get(), nss, fixLockModeForSystemDotViewsChanges(nss, MODE_IX)); + invariant(autoColl->getCollection()); + // Move locks into loader, so it now controls their lifetime. auto loader = std::make_unique<CollectionBulkLoaderImpl>(Client::releaseCurrent(), |