diff options
author | Louis Williams <louis.williams@mongodb.com> | 2020-02-24 23:03:00 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2020-02-24 23:03:00 +0000 |
commit | 73fb5d72b14681b683681f65eb16a332ae090f3d (patch) | |
tree | a2d5c0c1909191bb8f090d1a527e61a9dbbd7bcb /jstests/disk | |
parent | 3aea7a5bc17d86cf14a1abf417d029f0356ee05e (diff) | |
download | mongo-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.js | 95 |
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(); +})(); |