/** * Tests that performing a stepdown on the primary during a dropDatabase command doesn't result in * any crashes when setting the drop-pending flag back to false. * * @tags: [requires_replication] */ (function() { "use strict"; load("jstests/noPassthrough/libs/index_build.js"); const dbName = "test"; const collName = "coll"; const replSet = new ReplSetTest({nodes: 2}); replSet.startSet(); replSet.initiate(); const primary = replSet.getPrimary(); let testDB = primary.getDB(dbName); const testColl = testDB.getCollection(collName); var bulk = testColl.initializeUnorderedBulkOp(); for (var i = 0; i < 5; ++i) { bulk.insert({x: i}); } assert.commandWorked(bulk.execute()); replSet.awaitReplication(); IndexBuildTest.pauseIndexBuilds(testDB.getMongo()); const awaitIndexBuild = IndexBuildTest.startIndexBuild( testDB.getMongo(), testColl.getFullName(), {x: 1}, {}, [ErrorCodes.IndexBuildAborted]); IndexBuildTest.waitForIndexBuildToScanCollection(testDB, collName, "x_1"); const failpoint = "dropDatabaseHangAfterWaitingForIndexBuilds"; assert.commandWorked(primary.adminCommand({configureFailPoint: failpoint, mode: "alwaysOn"})); // Run the dropDatabase command and stepdown the primary while it is running. const awaitDropDatabase = startParallelShell(() => { assert.commandFailedWithCode(db.dropDatabase(), ErrorCodes.InterruptedDueToReplStateChange); }, testDB.getMongo().port); checkLog.containsJson(primary, 4612302); IndexBuildTest.resumeIndexBuilds(testDB.getMongo()); awaitIndexBuild(); // Ensure the dropDatabase command has begun before stepping down. checkLog.containsJson(primary, 4612300); assert.commandWorked(testDB.adminCommand({replSetStepDown: 60, force: true})); replSet.waitForState(primary, ReplSetTest.State.SECONDARY); assert.commandWorked(primary.adminCommand({configureFailPoint: failpoint, mode: "off"})); awaitDropDatabase(); const newPrimary = replSet.getPrimary(); assert(primary.port != newPrimary.port); // The {x: 1} index was aborted and should not be present even though the dropDatabase command was // interrupted. Only the _id index will exist. let indexesRes = assert.commandWorked(newPrimary.getDB(dbName).runCommand({listIndexes: collName})); assert.eq(1, indexesRes.cursor.firstBatch.length); indexesRes = assert.commandWorked(replSet.getSecondary().getDB(dbName).runCommand({listIndexes: collName})); assert.eq(1, indexesRes.cursor.firstBatch.length); // Run dropDatabase on the new primary. The secondary (formerly the primary) should be able to // drop the database too. newPrimary.getDB(dbName).dropDatabase(); replSet.awaitReplication(); replSet.stopSet(); })();