diff options
author | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2017-11-08 19:00:40 -0500 |
---|---|---|
committer | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2017-11-10 16:11:03 -0500 |
commit | 6a416de4330d6368ea77bace41e297082e8cf3bd (patch) | |
tree | a60d5ceb29d21671af91ebc2e308b3dfdd84515c | |
parent | b6895cfda235513493004e5f53d241f9f01cf92a (diff) | |
download | mongo-6a416de4330d6368ea77bace41e297082e8cf3bd.tar.gz |
SERVER-28251 Fix race condition in index_killop.js
-rw-r--r-- | jstests/noPassthrough/index_killop.js | 6 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_create_impl.cpp | 23 |
2 files changed, 13 insertions, 16 deletions
diff --git a/jstests/noPassthrough/index_killop.js b/jstests/noPassthrough/index_killop.js index 9ea3034ad9e..4908ea5ded9 100644 --- a/jstests/noPassthrough/index_killop.js +++ b/jstests/noPassthrough/index_killop.js @@ -47,9 +47,6 @@ // Kill the index build. assert.commandWorked(testDB.killOp(opId)); - assert.commandWorked( - testDB.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: 'off'})); - // Wait for the index build to stop. assert.soon(function() { return getIndexBuildOpId() == -1; @@ -62,6 +59,9 @@ // Check that no new index has been created. This verifies that the index build was aborted // rather than successfully completed. assert.eq([{_id: 1}], testDB.test.getIndexKeys()); + + assert.commandWorked( + testDB.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: 'off'})); } testAbortIndexBuild({background: true}); diff --git a/src/mongo/db/catalog/index_create_impl.cpp b/src/mongo/db/catalog/index_create_impl.cpp index 638b75765f5..598fe9fa581 100644 --- a/src/mongo/db/catalog/index_create_impl.cpp +++ b/src/mongo/db/catalog/index_create_impl.cpp @@ -320,11 +320,20 @@ Status MultiIndexBlockImpl::insertAllDocumentsInCollection(std::set<RecordId>* d PlanExecutor::ExecState state; int retries = 0; // non-zero when retrying our last document. while (retries || - (PlanExecutor::ADVANCED == (state = exec->getNextSnapshotted(&objToIndex, &loc)))) { + (PlanExecutor::ADVANCED == (state = exec->getNextSnapshotted(&objToIndex, &loc))) || + MONGO_FAIL_POINT(hangAfterStartingIndexBuild)) { try { if (_allowInterruption) _opCtx->checkForInterrupt(); + if (!(retries || (PlanExecutor::ADVANCED == state))) { + // The only reason we are still in the loop is hangAfterStartingIndexBuild. + log() << "Hanging index build due to 'hangAfterStartingIndexBuild' failpoint"; + invariant(_allowInterruption); + sleepmillis(1000); + continue; + } + // Make sure we are working with the latest version of the document. if (objToIndex.snapshotId() != _opCtx->recoveryUnit()->getSnapshotId() && !_collection->findDoc(_opCtx, loc, &objToIndex)) { @@ -383,18 +392,6 @@ Status MultiIndexBlockImpl::insertAllDocumentsInCollection(std::set<RecordId>* d WorkingSetCommon::toStatusString(objToIndex.value()), state == PlanExecutor::IS_EOF); - if (MONGO_FAIL_POINT(hangAfterStartingIndexBuild)) { - // Need the index build to hang before the progress meter is marked as finished so we can - // reliably check that the index build has actually started in js tests. - while (MONGO_FAIL_POINT(hangAfterStartingIndexBuild)) { - log() << "Hanging index build due to 'hangAfterStartingIndexBuild' failpoint"; - sleepmillis(1000); - } - - // Check for interrupt to allow for killop prior to index build completion. - _opCtx->checkForInterrupt(); - } - if (MONGO_FAIL_POINT(hangAfterStartingIndexBuildUnlocked)) { // Unlock before hanging so replication recognizes we've completed. Locker::LockSnapshot lockInfo; |