mongo/jstests/replsets/prepared_transaction_kill_during_step_up_refresh.js

75 lines
2.6 KiB
JavaScript

/**
* Tests that the work to restore locks for prepared transactions on step up is not killable via
* killSessions commands.
*
* @tags: [uses_transactions, uses_prepare_transaction]
*/
import {PrepareHelpers} from "jstests/core/txns/libs/prepare_helpers.js";
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
import {ReplSetTest} from "jstests/libs/replsettest.js";
import {reconnect} from "jstests/replsets/rslib.js";
const rst = new ReplSetTest({nodes: 2, name: jsTestName()});
rst.startSet();
rst.initiate();
const dbName = "primaryDB";
const collName = "testcoll";
const primary = rst.getPrimary();
const newPrimary = rst.getSecondary();
const primaryDB = primary.getDB(dbName);
const primaryColl = primaryDB.getCollection(collName);
assert.commandWorked(primaryDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
jsTestName("Starting a transaction");
const session = primary.startSession({causalConsistency: false});
session.startTransaction({writeConcern: {w: "majority"}});
const lsid = session.getSessionId().id;
jsTestLog("LSID for our session is " + tojson(lsid));
jsTestLog("Inserting a doc in a transaction.");
const doc = {
_id: "txnDoc",
};
assert.commandWorked(session.getDatabase(dbName).getCollection(collName).insert(doc));
jsTestLog("Putting transaction into prepare");
const prepareTimestamp = PrepareHelpers.prepareTransaction(session);
jsTestLog("Setting failpoint on new primary");
const stepUpFP = configureFailPoint(newPrimary, "hangDuringStepUpPrepareRestoreLocks");
jsTestLog("Stepping up new primary");
rst.stepUp(newPrimary, {awaitWritablePrimary: false});
reconnect(primary);
jsTestLog("Waiting on new primary to hit step up failpoint");
stepUpFP.wait();
jsTestLog("Killing the session");
const newPrimaryDB = newPrimary.getDB(dbName);
assert.commandWorked(newPrimaryDB.runCommand({killSessions: [{id: lsid}]}));
jsTestLog("Allowing step up to continue");
stepUpFP.off();
assert(newPrimary, rst.getPrimary());
// The prepare entry must be majority committed on the new primary before we issue the
// commitTransaction command.
jsTestLog("Ensure prepare entry made it into the committed snapshot on the new primary");
PrepareHelpers.awaitMajorityCommitted(rst, prepareTimestamp);
jsTestLog("Committing transaction on the new primary");
// Create a proxy session to reuse the session state of the old primary.
const newSession = new _DelegatingDriverSession(newPrimary, session);
assert.commandWorked(PrepareHelpers.commitTransaction(newSession, prepareTimestamp));
rst.awaitReplication();
assert.eq(doc, primaryColl.findOne({}), primaryColl.find({}).toArray());
rst.stopSet();