summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiangyu Yao <xiangyu.yao@mongodb.com>2017-11-08 19:00:40 -0500
committerXiangyu Yao <xiangyu.yao@mongodb.com>2017-11-10 16:11:03 -0500
commit6a416de4330d6368ea77bace41e297082e8cf3bd (patch)
treea60d5ceb29d21671af91ebc2e308b3dfdd84515c
parentb6895cfda235513493004e5f53d241f9f01cf92a (diff)
downloadmongo-6a416de4330d6368ea77bace41e297082e8cf3bd.tar.gz
SERVER-28251 Fix race condition in index_killop.js
-rw-r--r--jstests/noPassthrough/index_killop.js6
-rw-r--r--src/mongo/db/catalog/index_create_impl.cpp23
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;