0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/jstests/disk/repair_unfinished_indexes.js

96 lines
3.7 KiB
JavaScript

/**
* 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);
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,
// This parameter ensures that when the standalone starts up, it applies all unapplied oplog
// entries since the last shutdown. This "smooths out" a race condition in this test where
// the secondary can shut down without fully applying the 'startIndexBuild' oplog entry, and
// not advancing the stable timestamp to the top of the oplog.
{setParameter: 'recoverFromOplogAsStandalone=true'});
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();
})();