summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2020-03-24 16:57:03 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-25 18:51:49 +0000
commit578375788561cb6a77e651a54f230bcbdffb3492 (patch)
tree81c1c225e06bd3d8bb13fb765e6dccbe98414f1d /jstests
parent28db80106d7318a9a59cb96352de062466a45cea (diff)
downloadmongo-578375788561cb6a77e651a54f230bcbdffb3492.tar.gz
SERVER-47095 Secondaries voting to commit index builds already existing should handle exceptions
Diffstat (limited to 'jstests')
-rw-r--r--jstests/noPassthrough/rolling_index_builds_shutdown_early.js129
1 files changed, 129 insertions, 0 deletions
diff --git a/jstests/noPassthrough/rolling_index_builds_shutdown_early.js b/jstests/noPassthrough/rolling_index_builds_shutdown_early.js
new file mode 100644
index 00000000000..1f76c63c3f8
--- /dev/null
+++ b/jstests/noPassthrough/rolling_index_builds_shutdown_early.js
@@ -0,0 +1,129 @@
+/**
+ * Tests that secondaries already containing an index build started by the primary node vote for
+ * committing the index immediately and do not raise an exception if a shutdown occurs before the
+ * verdict.
+ *
+ * @tags: [
+ * requires_persistence,
+ * requires_replication,
+ * ]
+ */
+
+(function() {
+'use strict';
+
+load('jstests/noPassthrough/libs/index_build.js');
+
+const replTest = new ReplSetTest({
+ nodes: [
+ {},
+ {
+ // Disallow elections on secondary.
+ rsConfig: {
+ priority: 0,
+ votes: 0,
+ }
+ },
+ {
+ // Disallow elections on secondary.
+ rsConfig: {
+ priority: 0,
+ votes: 0,
+ }
+ },
+ ]
+});
+
+replTest.startSet();
+replTest.initiate();
+
+const dbName = 'test';
+const collName = 't';
+
+TestData.dbName = dbName;
+TestData.collName = collName;
+
+let primary = replTest.getPrimary();
+let primaryDB = primary.getDB(dbName);
+let coll = primaryDB.getCollection(collName);
+
+if (!IndexBuildTest.supportsTwoPhaseIndexBuild(primary)) {
+ jsTestLog('Two phase index builds not supported, skipping test.');
+ replTest.stopSet();
+ return;
+}
+
+// Populate the collection to avoid empty collection index build optimization.
+assert.commandWorked(coll.insert({x: 1, y: 1}));
+
+// Make sure the documents make it to the secondaries.
+replTest.awaitReplication();
+
+let secondaries = replTest.getSecondaries();
+const standalonePort = allocatePort();
+jsTestLog('Standalone server will listen on port: ' + standalonePort);
+
+function buildIndexOnNodeAsStandalone(node) {
+ jsTestLog('A. Restarting as standalone: ' + node.host);
+ replTest.stop(node, /*signal=*/null, /*opts=*/null, {forRestart: true, waitpid: true});
+ const standalone = MongoRunner.runMongod({
+ restart: true,
+ dbpath: node.dbpath,
+ port: standalonePort,
+ setParameter: {
+ disableLogicalSessionCacheRefresh: true,
+ ttlMonitorEnabled: false,
+ },
+ });
+ if (jsTestOptions().keyFile) {
+ assert(jsTest.authenticate(standalone),
+ 'Failed authentication during restart: ' + standalone.host);
+ }
+
+ jsTestLog('B. Building index on standalone: ' + standalone.host);
+ const standaloneDB = standalone.getDB(dbName);
+ const standaloneColl = standaloneDB.getCollection(collName);
+ assert.commandWorked(standaloneColl.createIndex({x: 1}, {name: 'rolling_index_x_1'}));
+
+ jsTestLog('C. Restarting as replica set node: ' + node.host);
+ MongoRunner.stopMongod(standalone);
+ replTest.restart(node);
+ replTest.awaitReplication();
+
+ let mongo = new Mongo(node.host);
+ mongo.setSlaveOk(true);
+ let indexes = mongo.getDB(dbName).getCollection(collName).getIndexes();
+ assert.eq(2, indexes.length);
+}
+
+buildIndexOnNodeAsStandalone(secondaries[0]);
+
+jsTestLog('D. Repeat the procedure for the remaining secondary: ' + secondaries[1].host);
+buildIndexOnNodeAsStandalone(secondaries[1]);
+
+replTest.awaitNodesAgreeOnPrimary(
+ replTest.kDefaultTimeoutMS, replTest.nodes, replTest.getNodeId(primary));
+
+secondaries = replTest.getSecondaries();
+
+// Enable fail points on the secondaries to prevent them from sending the commit quorum vote to the
+// primary.
+assert.commandWorked(secondaries[0].adminCommand(
+ {configureFailPoint: 'hangBeforeSendingCommitQuorumVote', mode: 'alwaysOn'}));
+assert.commandWorked(secondaries[1].adminCommand(
+ {configureFailPoint: 'hangBeforeSendingCommitQuorumVote', mode: 'alwaysOn'}));
+
+jsTestLog('E. Build index on the primary: ' + primary.host);
+startParallelShell(() => {
+ const coll = db.getSiblingDB(TestData.dbName).getCollection(TestData.collName);
+ coll.createIndex({x: 1}, {name: 'rolling_index_x_1'}, 3);
+}, primary.port);
+
+checkLog.containsJson(secondaries[0], 4709501);
+checkLog.containsJson(secondaries[1], 4709501);
+
+replTest.stop(secondaries[0], /*signal=*/null, /*opts=*/null, {waitpid: true});
+replTest.stop(secondaries[1], /*signal=*/null, /*opts=*/null, {waitpid: true});
+
+replTest.stop(primary, /*signal=*/null, /*opts=*/null, {waitpid: true});
+}());