74 lines
3.1 KiB
JavaScript
74 lines
3.1 KiB
JavaScript
/**
|
|
* Test that rollbackViaRefetch survives an attempt to drop a collection that does not exist.
|
|
* This test simulates a scenario where a collection is dropped during the first rollback
|
|
* attempt.
|
|
*
|
|
* We use a failpoint to ensure the collection was dropped before forcing rollback to return
|
|
* early with a recoverable error. We then turn this failpoint off so that the second attempt
|
|
* can succeed even though the collection has already been dropped.
|
|
*
|
|
*/
|
|
|
|
(function() {
|
|
"use strict";
|
|
load("jstests/libs/check_log.js");
|
|
load("jstests/replsets/libs/rollback_test.js");
|
|
|
|
const dbName = "test";
|
|
const collName = "rollback_via_refetch_survives_nonexistent_collection_drop";
|
|
|
|
// Provide RollbackTest with custom ReplSetTest so we can set enableMajorityReadConcern.
|
|
const rst = new ReplSetTest({
|
|
name: collName,
|
|
nodes: 3,
|
|
useBridge: true,
|
|
nodeOptions: {enableMajorityReadConcern: "false"}
|
|
});
|
|
|
|
rst.startSet();
|
|
const config = rst.getReplSetConfig();
|
|
config.members[2].priority = 0;
|
|
config.settings = {chainingAllowed: false};
|
|
rst.initiate(config);
|
|
|
|
const rollbackTest = new RollbackTest(collName, rst);
|
|
|
|
// Stop replication from the current primary, the rollback node.
|
|
const rollbackNode = rollbackTest.transitionToRollbackOperations();
|
|
const rollbackDB = rollbackNode.getDB(dbName);
|
|
|
|
jsTestLog("Turning on the rollbackExitEarlyAfterCollectionDrop fail point");
|
|
assert.commandWorked(rollbackDB.adminCommand(
|
|
{configureFailPoint: 'rollbackExitEarlyAfterCollectionDrop', mode: 'alwaysOn'}));
|
|
|
|
// Create a collection on the rollback node.
|
|
assert.commandWorked(rollbackDB.runCommand({create: collName}));
|
|
|
|
// Step down the current primary and elect the node that does not have the collection.
|
|
rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
|
|
|
|
jsTestLog("Attempting to roll back.");
|
|
// Make the old primary rollback against the new primary. This attempt should fail because the
|
|
// rollbackExitEarlyAfterCollectionDrop fail point is set. We fail with a recoverable error
|
|
// so that the rollback will be retried.
|
|
rollbackTest.transitionToSyncSourceOperationsDuringRollback();
|
|
|
|
// Make sure we exit the rollback early by checking for the correct log messages.
|
|
checkLog.contains(rollbackDB.getMongo(),
|
|
"rollbackExitEarlyAfterCollectionDrop fail point enabled.");
|
|
|
|
jsTestLog("Turning off the rollbackExitEarlyAfterCollectionDrop fail point");
|
|
// A rollback attempt after turning off the fail point should succeed even if we already
|
|
// dropped the collection.
|
|
assert.commandWorked(rollbackDB.adminCommand(
|
|
{configureFailPoint: 'rollbackExitEarlyAfterCollectionDrop', mode: 'off'}));
|
|
|
|
rollbackTest.transitionToSteadyStateOperations();
|
|
|
|
// After a successful rollback attempt, we should have seen the following log message to ensure
|
|
// that we tried to drop a non-existent collection and continued without acquiring a database
|
|
// lock.
|
|
checkLog.contains(rollbackDB.getMongo(), "This collection does not exist");
|
|
|
|
rollbackTest.stop();
|
|
}()); |