summaryrefslogtreecommitdiff
path: root/jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js')
-rw-r--r--jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js207
1 files changed, 103 insertions, 104 deletions
diff --git a/jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js b/jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js
index 237fc1880fc..d5568cedf99 100644
--- a/jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js
+++ b/jstests/replsets/kill_reads_with_prepare_conflicts_during_step_down.js
@@ -6,108 +6,107 @@
*/
(function() {
- "use strict";
-
- load("jstests/core/txns/libs/prepare_helpers.js");
- load("jstests/libs/check_log.js");
-
- // Start one of the nodes with priority: 0 to avoid elections.
- var rst = new ReplSetTest({nodes: [{}, {rsConfig: {priority: 0}}]});
- rst.startSet();
- rst.initiate();
-
- let primary = rst.getPrimary();
-
- const dbName = "test";
- const collName = "kill_reads_with_prepare_conflicts_during_step_down";
-
- const primaryDB = primary.getDB(dbName);
- // Used to make sure that the correct amount of operations were killed on this node
- // during stepdown.
- const primaryAdmin = primary.getDB("admin");
- const primaryColl = primaryDB[collName];
-
- let session = primary.startSession();
- const sessionID = session.getSessionId();
- let sessionDB = session.getDatabase(dbName);
- const sessionColl = sessionDB.getCollection(collName);
-
- assert.commandWorked(primaryAdmin.adminCommand(
- {configureFailPoint: "WTPrintPrepareConflictLog", mode: "alwaysOn"}));
-
- // Insert a document that we will later modify in a transaction.
- assert.commandWorked(primaryColl.insert({_id: 1}));
-
- jsTestLog("Start a transaction and prepare it");
- session.startTransaction();
- assert.commandWorked(sessionColl.update({_id: 1}, {_id: 1, a: 1}));
- const prepareTimestamp = PrepareHelpers.prepareTransaction(session);
-
- TestData.dbName = dbName;
- TestData.collName = collName;
-
- const readBlockedOnPrepareConflictThread = startParallelShell(() => {
- const parallelTestDB = db.getSiblingDB(TestData.dbName);
- const parallelTestCollName = TestData.collName;
-
- // Advance the clusterTime with another insert.
- let res = assert.commandWorked(parallelTestDB.runCommand(
- {insert: parallelTestCollName, documents: [{advanceClusterTime: 1}]}));
- assert(res.hasOwnProperty("$clusterTime"), res);
- assert(res.$clusterTime.hasOwnProperty("clusterTime"), res);
- const clusterTime = res.$clusterTime.clusterTime;
- jsTestLog("Using afterClusterTime: " + clusterTime);
-
- // The following read should block on the prepared transaction since it will be
- // reading a conflicting document using an afterClusterTime later than the
- // prepareTimestamp.
- assert.commandFailedWithCode(parallelTestDB.runCommand({
- find: parallelTestCollName,
- filter: {_id: 1},
- readConcern: {afterClusterTime: clusterTime}
- }),
- ErrorCodes.InterruptedDueToReplStateChange);
- }, primary.port);
-
- jsTestLog("Waiting for failpoint");
- checkLog.contains(primary, "WTPrintPrepareConflictLog fail point enabled");
-
- // Once we have confirmed that the find command has hit a prepare conflict, we can perform
- // a step down.
- jsTestLog("Stepping down primary");
- assert.commandWorked(
- primaryAdmin.adminCommand({replSetStepDown: 60 * 10 /* 10 minutes */, force: true}));
-
- readBlockedOnPrepareConflictThread();
-
- rst.waitForState(primary, ReplSetTest.State.SECONDARY);
-
- // Validate that the read operation got killed during step down.
- let replMetrics =
- assert.commandWorked(primaryAdmin.adminCommand({serverStatus: 1})).metrics.repl;
- assert.eq(replMetrics.stepDown.userOperationsKilled, 1);
-
- // Allow the primary to be re-elected, and wait for it.
- assert.commandWorked(primaryAdmin.adminCommand({replSetFreeze: 0}));
- primary = rst.getPrimary();
-
- // Make sure we can successfully commit the prepared transaction.
- jsTestLog("Restoring shell session state");
- session = PrepareHelpers.createSessionWithGivenId(primary, sessionID);
- sessionDB = session.getDatabase(dbName);
- // The transaction on this session should have a txnNumber of 0. We explicitly set this
- // since createSessionWithGivenId does not restore the current txnNumber in the shell.
- session.setTxnNumber_forTesting(0);
- const txnNumber = session.getTxnNumber_forTesting();
-
- jsTestLog("Committing transaction");
- // Commit the transaction.
- assert.commandWorked(sessionDB.adminCommand({
- commitTransaction: 1,
- commitTimestamp: prepareTimestamp,
- txnNumber: NumberLong(txnNumber),
- autocommit: false,
- }));
-
- rst.stopSet();
+"use strict";
+
+load("jstests/core/txns/libs/prepare_helpers.js");
+load("jstests/libs/check_log.js");
+
+// Start one of the nodes with priority: 0 to avoid elections.
+var rst = new ReplSetTest({nodes: [{}, {rsConfig: {priority: 0}}]});
+rst.startSet();
+rst.initiate();
+
+let primary = rst.getPrimary();
+
+const dbName = "test";
+const collName = "kill_reads_with_prepare_conflicts_during_step_down";
+
+const primaryDB = primary.getDB(dbName);
+// Used to make sure that the correct amount of operations were killed on this node
+// during stepdown.
+const primaryAdmin = primary.getDB("admin");
+const primaryColl = primaryDB[collName];
+
+let session = primary.startSession();
+const sessionID = session.getSessionId();
+let sessionDB = session.getDatabase(dbName);
+const sessionColl = sessionDB.getCollection(collName);
+
+assert.commandWorked(
+ primaryAdmin.adminCommand({configureFailPoint: "WTPrintPrepareConflictLog", mode: "alwaysOn"}));
+
+// Insert a document that we will later modify in a transaction.
+assert.commandWorked(primaryColl.insert({_id: 1}));
+
+jsTestLog("Start a transaction and prepare it");
+session.startTransaction();
+assert.commandWorked(sessionColl.update({_id: 1}, {_id: 1, a: 1}));
+const prepareTimestamp = PrepareHelpers.prepareTransaction(session);
+
+TestData.dbName = dbName;
+TestData.collName = collName;
+
+const readBlockedOnPrepareConflictThread = startParallelShell(() => {
+ const parallelTestDB = db.getSiblingDB(TestData.dbName);
+ const parallelTestCollName = TestData.collName;
+
+ // Advance the clusterTime with another insert.
+ let res = assert.commandWorked(parallelTestDB.runCommand(
+ {insert: parallelTestCollName, documents: [{advanceClusterTime: 1}]}));
+ assert(res.hasOwnProperty("$clusterTime"), res);
+ assert(res.$clusterTime.hasOwnProperty("clusterTime"), res);
+ const clusterTime = res.$clusterTime.clusterTime;
+ jsTestLog("Using afterClusterTime: " + clusterTime);
+
+ // The following read should block on the prepared transaction since it will be
+ // reading a conflicting document using an afterClusterTime later than the
+ // prepareTimestamp.
+ assert.commandFailedWithCode(parallelTestDB.runCommand({
+ find: parallelTestCollName,
+ filter: {_id: 1},
+ readConcern: {afterClusterTime: clusterTime}
+ }),
+ ErrorCodes.InterruptedDueToReplStateChange);
+}, primary.port);
+
+jsTestLog("Waiting for failpoint");
+checkLog.contains(primary, "WTPrintPrepareConflictLog fail point enabled");
+
+// Once we have confirmed that the find command has hit a prepare conflict, we can perform
+// a step down.
+jsTestLog("Stepping down primary");
+assert.commandWorked(
+ primaryAdmin.adminCommand({replSetStepDown: 60 * 10 /* 10 minutes */, force: true}));
+
+readBlockedOnPrepareConflictThread();
+
+rst.waitForState(primary, ReplSetTest.State.SECONDARY);
+
+// Validate that the read operation got killed during step down.
+let replMetrics = assert.commandWorked(primaryAdmin.adminCommand({serverStatus: 1})).metrics.repl;
+assert.eq(replMetrics.stepDown.userOperationsKilled, 1);
+
+// Allow the primary to be re-elected, and wait for it.
+assert.commandWorked(primaryAdmin.adminCommand({replSetFreeze: 0}));
+primary = rst.getPrimary();
+
+// Make sure we can successfully commit the prepared transaction.
+jsTestLog("Restoring shell session state");
+session = PrepareHelpers.createSessionWithGivenId(primary, sessionID);
+sessionDB = session.getDatabase(dbName);
+// The transaction on this session should have a txnNumber of 0. We explicitly set this
+// since createSessionWithGivenId does not restore the current txnNumber in the shell.
+session.setTxnNumber_forTesting(0);
+const txnNumber = session.getTxnNumber_forTesting();
+
+jsTestLog("Committing transaction");
+// Commit the transaction.
+assert.commandWorked(sessionDB.adminCommand({
+ commitTransaction: 1,
+ commitTimestamp: prepareTimestamp,
+ txnNumber: NumberLong(txnNumber),
+ autocommit: false,
+}));
+
+rst.stopSet();
})(); \ No newline at end of file