summaryrefslogtreecommitdiff
path: root/jstests/disk
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2020-02-24 23:03:00 +0000
committerevergreen <evergreen@mongodb.com>2020-02-24 23:03:00 +0000
commit73fb5d72b14681b683681f65eb16a332ae090f3d (patch)
treea2d5c0c1909191bb8f090d1a527e61a9dbbd7bcb /jstests/disk
parent3aea7a5bc17d86cf14a1abf417d029f0356ee05e (diff)
downloadmongo-73fb5d72b14681b683681f65eb16a332ae090f3d.tar.gz
SERVER-38714 Drop unfinished indexes on modified collections during repair when run on a replica set node
Diffstat (limited to 'jstests/disk')
-rw-r--r--jstests/disk/repair_unfinished_indexes.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/jstests/disk/repair_unfinished_indexes.js b/jstests/disk/repair_unfinished_indexes.js
new file mode 100644
index 00000000000..0f5846757b1
--- /dev/null
+++ b/jstests/disk/repair_unfinished_indexes.js
@@ -0,0 +1,95 @@
+/**
+ * This test shuts down a replica set during a two-phase index build. The test corrupts a WiredTiger
+ * collection file and expects that --repair salvages the data and drops the unfinished index.
+ *
+ * @tags: [requires_wiredtiger, requires_replication]
+ */
+
+(function() {
+
+load('jstests/disk/libs/wt_file_helper.js');
+load('jstests/noPassthrough/libs/index_build.js');
+
+const dbName = "repair_unfinished_indexes";
+const collName = "test";
+
+const replSet = new ReplSetTest({nodes: 2});
+replSet.startSet();
+replSet.initiate();
+
+const primary = replSet.getPrimary();
+const primaryDB = primary.getDB(dbName);
+
+if (!IndexBuildTest.supportsTwoPhaseIndexBuild(primary)) {
+ jsTestLog('Two phase index builds not supported, skipping test.');
+ rst.stopSet();
+ return;
+}
+
+const secondary = replSet.getSecondary();
+const secondaryDB = secondary.getDB(dbName);
+const secondaryPort = secondary.port;
+const secondaryDbpath = secondary.dbpath;
+
+const primaryColl = primaryDB.getCollection(collName);
+
+assert.commandWorked(primaryColl.insert({_id: 0, a: 1}));
+
+jsTestLog("Starting index build on primary and pausing before completion");
+IndexBuildTest.pauseIndexBuilds(primary);
+const createIdx = IndexBuildTest.startIndexBuild(primary, primaryColl.getFullName(), {a: 1});
+
+jsTestLog("Waiting for secondary to start the index build");
+IndexBuildTest.waitForIndexBuildToStart(secondaryDB);
+
+const secondaryCollUri = getUriForColl(secondaryDB[collName]);
+replSet.stop(secondary);
+
+// Confirm that the secondary node leaves the index as unfinished.
+(function startAsStandalone() {
+ jsTestLog("Starting secondary as standalone");
+ const mongod = startMongodOnExistingPath(secondaryDbpath);
+ IndexBuildTest.assertIndexes(mongod.getDB(dbName).getCollection(collName),
+ 2,
+ ["_id_"],
+ ["a_1"],
+ {includeBuildUUIDs: true});
+ MongoRunner.stopMongod(mongod);
+})();
+
+const exitCode = createIdx({checkExitSuccess: false});
+assert.neq(0, exitCode, 'expected shell to exit abnormally due to shutdown');
+
+const secondaryCollFile = secondaryDbpath + "/" + secondaryCollUri + ".wt";
+jsTestLog("Corrupting secondary collection file: " + secondaryCollFile);
+corruptFile(secondaryCollFile);
+assertRepairSucceeds(secondaryDbpath, secondaryPort);
+
+// Importantly, confirm that the secondary node dropped the unfinished index.
+(function startAsStandaloneAfterRepair() {
+ jsTestLog("Starting secondary as standalone after repair");
+ const mongod = startMongodOnExistingPath(secondaryDbpath);
+ IndexBuildTest.assertIndexes(
+ mongod.getDB(dbName).getCollection(collName), 1, ["_id_"], [], {includeBuildUUIDs: true});
+ MongoRunner.stopMongod(mongod);
+})();
+
+// The secondary may not be reintroduced because data was modified.
+assertErrorOnStartupWhenStartingAsReplSet(
+ secondaryDbpath, secondaryPort, replSet.getReplSetConfig()._id);
+
+(function reSyncSecondary() {
+ jsTestLog("Wiping dbpath and re-syncing secondary");
+ const newSecondary = assertStartInReplSet(
+ replSet, secondary, true /* cleanData */, true /* expectResync */, function(node) {});
+
+ IndexBuildTest.resumeIndexBuilds(primary);
+ IndexBuildTest.waitForIndexBuildToStop(primaryDB);
+ replSet.awaitReplication();
+ IndexBuildTest.assertIndexes(primaryColl, 2, ["_id_", "a_1"]);
+ IndexBuildTest.assertIndexes(
+ newSecondary.getDB(dbName).getCollection(collName), 2, ["_id_", "a_1"]);
+})();
+
+replSet.stopSet();
+})();