73 lines
3.0 KiB
JavaScript
73 lines
3.0 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/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.initiateWithHighElectionTimeout(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'}));
|
|
|
|
// 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. This check has to be before transitionToSteadyStateOperations() to make sure ram logs
|
|
// are not overwritten due to oplog fether retry error.
|
|
checkLog.containsJson(rollbackDB.getMongo(), 21696); // This collection does not exist
|
|
|
|
rollbackTest.transitionToSteadyStateOperations();
|
|
|
|
rollbackTest.stop();
|
|
}());
|