summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-12-20 21:20:38 +0000
committerevergreen <evergreen@mongodb.com>2019-12-20 21:20:38 +0000
commit0e079cef6ba967a3cc930c6fb7960a9125a387ad (patch)
treea57b047678d5035061f82ee0f3e819ec7a17e7f5 /src/mongo/db
parentc4d21d70c7ae90d1ef8635ff81cfc58d8926c770 (diff)
downloadmongo-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.cpp23
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp25
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(),