summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2016-09-28 10:46:08 -0400
committerJames Wahlin <james.wahlin@10gen.com>2016-10-03 09:02:34 -0400
commitab912a90501ffa988591ab5173773b538cc22cac (patch)
tree496cbb3d6ee0484ec3b7982be27dd5201c864d34
parent445abe2e01db50dad295ba8af4971eb243b02546 (diff)
downloadmongo-ab912a90501ffa988591ab5173773b538cc22cac.tar.gz
SERVER-26367 index_killop.js should use failpoint
-rw-r--r--jstests/noPassthrough/index_killop.js69
-rw-r--r--jstests/noPassthroughWithMongod/index_killop.js63
-rw-r--r--src/mongo/db/catalog/index_create.cpp16
3 files changed, 80 insertions, 68 deletions
diff --git a/jstests/noPassthrough/index_killop.js b/jstests/noPassthrough/index_killop.js
new file mode 100644
index 00000000000..734053ce06a
--- /dev/null
+++ b/jstests/noPassthrough/index_killop.js
@@ -0,0 +1,69 @@
+/**
+ * Confirms that both foreground and background index builds can be aborted using killop.
+ */
+(function() {
+ "use strict";
+
+ const conn = MongoRunner.runMongod({smallfiles: "", nojournal: ""});
+ assert.neq(null, conn, "mongod was unable to start up");
+
+ const testDB = conn.getDB("test");
+ assert.commandWorked(testDB.dropDatabase());
+ testDB.test.insertOne({a: 1});
+
+ // Returns the op id for the running index build, or -1 if there is no current index build.
+ function getIndexBuildOpId() {
+ const result = testDB.currentOp();
+ assert.commandWorked(result);
+ let indexBuildOpId = -1;
+
+ result.inprog.forEach(function(op) {
+ // Identify the index build as the createIndex command
+ // It is assumed that no other clients are concurrently
+ // accessing the 'test' database.
+ if ((op.op == 'query' || op.op == 'command') && 'createIndexes' in op.query) {
+ indexBuildOpId = op.opid;
+ }
+ });
+ return indexBuildOpId;
+ }
+
+ // Test that building an index with 'options' can be aborted using killop.
+ function testAbortIndexBuild(options) {
+ assert.commandWorked(testDB.adminCommand(
+ {configureFailPoint: 'hangAfterStartingIndexBuild', mode: 'alwaysOn'}));
+
+ const createIdx = startParallelShell(
+ "let coll = db.getSiblingDB('test').test;" +
+ "assert.commandWorked(coll.createIndex({ a: 1 }, " + tojson(options) + "));",
+ conn.port);
+
+ // When the index build starts, find its op id.
+ let opId;
+ assert.soon(function() {
+ return (opId = getIndexBuildOpId()) != -1;
+ }, "Index build operation not found after starting via parallelShell");
+
+ // 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;
+ });
+
+ const exitCode = createIdx({checkExitSuccess: false});
+ assert.neq(
+ 0, exitCode, 'expected shell to exit abnormally due to index build being terminated');
+
+ // 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());
+ }
+
+ testAbortIndexBuild({background: true});
+ testAbortIndexBuild({background: false});
+})();
diff --git a/jstests/noPassthroughWithMongod/index_killop.js b/jstests/noPassthroughWithMongod/index_killop.js
deleted file mode 100644
index 95b0f995848..00000000000
--- a/jstests/noPassthroughWithMongod/index_killop.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Both foreground and background index builds can be aborted using killop. SERVER-3067
-
-t = db.jstests_slownightly_index_killop;
-t.drop();
-
-// Insert a large number of documents, enough to ensure that an index build on these documents will
-// be interrupted before complete.
-var bulk = t.initializeUnorderedBulkOp();
-for (i = 0; i < 1e6; ++i) {
- bulk.insert({a: i});
-}
-assert.writeOK(bulk.execute());
-
-function debug(x) {
- // printjson( x );
-}
-
-/** @return the op id for the running index build, or -1 if there is no current index build. */
-function getIndexBuildOpId() {
- inprog = db.currentOp().inprog;
- debug(inprog);
- indexBuildOpId = -1;
- inprog.forEach(function(op) {
- // Identify the index build as the createIndex command
- // It is assumed that no other clients are concurrently
- // accessing the 'test' database.
- if ((op.op == 'query' || op.op == 'command') && 'createIndexes' in op.query) {
- debug(op.opid);
- indexBuildOpId = op.opid;
- }
- });
- return indexBuildOpId;
-}
-
-/** Test that building an index with @param 'options' can be aborted using killop. */
-function testAbortIndexBuild(options) {
- var createIdx = startParallelShell('var coll = db.jstests_slownightly_index_killop;' +
- 'assert.commandWorked(coll.createIndex({ a: 1 }, ' +
- tojson(options) + '));');
-
- // When the index build starts, find its op id.
- assert.soon(function() {
- return (opId = getIndexBuildOpId()) != -1;
- });
- // Kill the index build.
- db.killOp(opId);
-
- // Wait for the index build to stop.
- assert.soon(function() {
- return getIndexBuildOpId() == -1;
- });
-
- var exitCode = createIdx({checkExitSuccess: false});
- assert.neq(
- 0, exitCode, 'expected shell to exit abnormally due to index build being terminated');
-
- // Check that no new index has been created. This verifies that the index build was aborted
- // rather than successfully completed.
- assert.eq([{_id: 1}], t.getIndexKeys());
-}
-
-testAbortIndexBuild({background: false});
-testAbortIndexBuild({background: true});
diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp
index 4527e6cf2dc..823dacff550 100644
--- a/src/mongo/db/catalog/index_create.cpp
+++ b/src/mongo/db/catalog/index_create.cpp
@@ -329,12 +329,18 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(std::set<RecordId>* dupsO
WorkingSetCommon::toStatusString(objToIndex.value()),
state == PlanExecutor::IS_EOF);
- // 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);
+ 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.
+ _txn->checkForInterrupt();
}
+
if (MONGO_FAIL_POINT(hangAfterStartingIndexBuildUnlocked)) {
// Unlock before hanging so replication recognizes we've completed.
Locker::LockSnapshot lockInfo;