summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2018-10-11 18:24:20 -0400
committerGregory Wlodarek <gregory.wlodarek@mongodb.com>2018-10-11 18:24:20 -0400
commit0272ec068f5da65458d7a081beac583b33b610d1 (patch)
tree681334367ffc8b799f54ab61f064ace04e76fb68
parent34de1953a9575f2745a1f430f5eb7ce2a6014031 (diff)
downloadmongo-0272ec068f5da65458d7a081beac583b33b610d1.tar.gz
SERVER-37055 IndexBuildBlock::fail() should grab a lock
-rw-r--r--jstests/noPassthrough/indexbg_shutdown.js19
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp3
-rw-r--r--src/mongo/db/catalog/index_create_impl.cpp4
-rw-r--r--src/mongo/db/index_builder.cpp7
4 files changed, 25 insertions, 8 deletions
diff --git a/jstests/noPassthrough/indexbg_shutdown.js b/jstests/noPassthrough/indexbg_shutdown.js
index d226613c9e7..a02e9c04294 100644
--- a/jstests/noPassthrough/indexbg_shutdown.js
+++ b/jstests/noPassthrough/indexbg_shutdown.js
@@ -29,6 +29,8 @@
var master = replTest.getPrimary();
var second = replTest.getSecondary();
+ var secondaryId = replTest.getNodeId(second);
+
var masterDB = master.getDB(dbname);
var secondDB = second.getDB(dbname);
@@ -36,7 +38,7 @@
jsTest.log("creating test data " + size + " documents");
var bulk = masterDB.getCollection(collection).initializeUnorderedBulkOp();
for (var i = 0; i < size; ++i) {
- bulk.insert({i: i});
+ bulk.insert({i: i, j: i * i});
}
assert.writeOK(bulk.execute());
@@ -49,14 +51,19 @@
// the background index build finishes).
assert.commandWorked(masterDB.runCommand({
createIndexes: collection,
- indexes: [{key: {i: 1}, name: "i1", background: true}],
+ indexes: [
+ {key: {i: -1, j: -1}, name: 'ij1', background: true},
+ {key: {i: -1, j: 1}, name: 'ij2', background: true},
+ {key: {i: 1, j: -1}, name: 'ij3', background: true},
+ {key: {i: 1, j: 1}, name: 'ij4', background: true}
+ ],
writeConcern: {w: 2}
}));
- assert.eq(2, masterDB.getCollection(collection).getIndexes().length);
+ assert.eq(5, masterDB.getCollection(collection).getIndexes().length);
- // Secondary should shut down cleanly, and not return an fassert. This is checked when we
- // shut down the ReplSetTest.
- second.getDB("admin").shutdownServer();
+ jsTest.log("Restarting secondary to retry replication");
+ // Secondary should restart cleanly.
+ replTest.restart(secondaryId, {}, /*wait=*/true);
replTest.stopSet();
}());
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index f2a255efba5..a0e1f3f0128 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -378,6 +378,9 @@ void IndexCatalogImpl::IndexBuildBlock::fail() {
invariant(_opCtx->lockState()->inAWriteUnitOfWork());
fassert(17204, _catalog->_getCollection()->ok()); // defensive
+ NamespaceString ns(_indexNamespace);
+ invariant(_opCtx->lockState()->isDbLockedForMode(ns.db(), MODE_X));
+
IndexCatalogEntry* entry = IndexCatalog::_getEntries(_catalog).find(_indexName);
invariant(entry == _entry);
diff --git a/src/mongo/db/catalog/index_create_impl.cpp b/src/mongo/db/catalog/index_create_impl.cpp
index e20b190b265..4aaacd3e429 100644
--- a/src/mongo/db/catalog/index_create_impl.cpp
+++ b/src/mongo/db/catalog/index_create_impl.cpp
@@ -370,8 +370,8 @@ Status MultiIndexBlockImpl::insertAllDocumentsInCollection() {
(PlanExecutor::ADVANCED == (state = exec->getNextSnapshotted(&objToIndex, &loc))) ||
MONGO_FAIL_POINT(hangAfterStartingIndexBuild)) {
try {
- if (_allowInterruption)
- _opCtx->checkForInterrupt();
+ if (_allowInterruption && !_opCtx->checkForInterruptNoAssert().isOK())
+ return _opCtx->checkForInterruptNoAssert();
if (!(retries || PlanExecutor::ADVANCED == state) ||
MONGO_FAIL_POINT(slowBackgroundIndexBuild)) {
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp
index f5d4fa472d2..d4ef6171228 100644
--- a/src/mongo/db/index_builder.cpp
+++ b/src/mongo/db/index_builder.cpp
@@ -232,6 +232,13 @@ Status IndexBuilder::_build(OperationContext* opCtx,
status = indexer.insertAllDocumentsInCollection();
}
if (!status.isOK()) {
+ if (allowBackgroundBuilding) {
+ UninterruptibleLockGuard noInterrupt(opCtx->lockState());
+ dbLock->relockWithMode(MODE_X);
+ if (status == ErrorCodes::InterruptedAtShutdown)
+ return _failIndexBuild(indexer, status, allowBackgroundBuilding);
+ opCtx->checkForInterrupt();
+ }
return _failIndexBuild(indexer, status, allowBackgroundBuilding);
}