summaryrefslogtreecommitdiff
path: root/jstests/replsets/transactions_after_rollback_via_refetch.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/replsets/transactions_after_rollback_via_refetch.js')
-rw-r--r--jstests/replsets/transactions_after_rollback_via_refetch.js223
1 files changed, 112 insertions, 111 deletions
diff --git a/jstests/replsets/transactions_after_rollback_via_refetch.js b/jstests/replsets/transactions_after_rollback_via_refetch.js
index cb9ea1c3257..463d70f4489 100644
--- a/jstests/replsets/transactions_after_rollback_via_refetch.js
+++ b/jstests/replsets/transactions_after_rollback_via_refetch.js
@@ -7,115 +7,116 @@
* @tags: [uses_transactions]
*/
(function() {
- 'use strict';
-
- load("jstests/replsets/libs/rollback_test.js");
-
- let name = "transactions_after_rollback_via_refetch";
- let dbName = name;
- let crudCollName = "crudColl";
- let collToDropName = "collToDrop";
-
- let CommonOps = (node) => {
- // Insert a couple of documents that will initially be present on all nodes.
- let crudColl = node.getDB(dbName)[crudCollName];
- assert.commandWorked(crudColl.insert({_id: 0}));
- assert.commandWorked(crudColl.insert({_id: 1}));
-
- // Create a collection so it can be dropped on the rollback node.
- node.getDB(dbName)[collToDropName].insert({_id: 0});
- };
-
- // We want to have the rollback node perform some inserts, updates, and deletes locally
- // during the rollback process, so we can ensure that transactions will read correct data
- // post-rollback, even though these writes will be un-timestamped.
- let RollbackOps = (node) => {
- let crudColl = node.getDB(dbName)[crudCollName];
- // Roll back an update (causes refetch and local update).
- assert.commandWorked(crudColl.update({_id: 0}, {$set: {rollbackNode: 0}}));
- // Roll back a delete (causes refetch and local insert).
- assert.commandWorked(crudColl.remove({_id: 1}));
- // Roll back an insert (causes local delete).
- assert.commandWorked(crudColl.insert({_id: 2}));
-
- // Roll back a drop (re-creates the collection).
- node.getDB(dbName)[collToDropName].drop();
- };
-
- let SyncSourceOps = (node) => {
- let coll = node.getDB(dbName)[crudCollName];
- // Update these docs so the rollback node will refetch them.
- assert.commandWorked(coll.update({_id: 0}, {$set: {syncSource: 0}}));
- assert.commandWorked(coll.update({_id: 1}, {$set: {syncSource: 1}}));
- };
-
- // Set up a replica set for use in RollbackTest. We disable majority reads on all nodes so that
- // they will use the "rollbackViaRefetch" algorithm.
- let replTest = new ReplSetTest({
- name,
- nodes: 3,
- useBridge: true,
- settings: {chainingAllowed: false},
- nodeOptions: {enableMajorityReadConcern: "false"}
- });
- replTest.startSet();
- let config = replTest.getReplSetConfig();
- config.members[2].priority = 0;
- replTest.initiate(config);
-
- let rollbackTest = new RollbackTest(name, replTest);
-
- CommonOps(rollbackTest.getPrimary());
-
- let rollbackNode = rollbackTest.transitionToRollbackOperations();
- RollbackOps(rollbackNode);
-
- let syncSourceNode = rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
- SyncSourceOps(syncSourceNode);
-
- // Wait for rollback to finish.
- rollbackTest.transitionToSyncSourceOperationsDuringRollback();
- rollbackTest.transitionToSteadyStateOperations();
-
- // Make the rollback node primary so we can run transactions against it.
- rollbackTest.getTestFixture().stepUp(rollbackNode);
-
- jsTestLog("Testing transactions against the node that just rolled back.");
- const sessionOptions = {causalConsistency: false};
- let session = rollbackNode.getDB(dbName).getMongo().startSession(sessionOptions);
- let sessionDb = session.getDatabase(dbName);
- let sessionColl = sessionDb[crudCollName];
-
- // Make sure we can do basic CRUD ops inside a transaction and read the data back correctly, pre
- // and post-commit.
- session.startTransaction();
- // Make sure we read from the snapshot correctly.
- assert.docEq(sessionColl.find().sort({_id: 1}).toArray(),
- [{_id: 0, syncSource: 0}, {_id: 1, syncSource: 1}]);
- // Do some basic ops.
- assert.commandWorked(sessionColl.update({_id: 0}, {$set: {inTxn: 1}}));
- assert.commandWorked(sessionColl.remove({_id: 1}));
- assert.commandWorked(sessionColl.insert({_id: 2}));
- // Make sure we read the updated data correctly.
- assert.docEq(sessionColl.find().sort({_id: 1}).toArray(),
- [{_id: 0, syncSource: 0, inTxn: 1}, {_id: 2}]);
- assert.commandWorked(session.commitTransaction_forTesting());
-
- // Make sure data is visible after commit.
- assert.docEq(sessionColl.find().sort({_id: 1}).toArray(),
- [{_id: 0, syncSource: 0, inTxn: 1}, {_id: 2}]);
-
- // Run a transaction that touches the collection that was re-created during rollback.
- sessionColl = sessionDb[collToDropName];
- session.startTransaction();
- assert.docEq(sessionColl.find().sort({_id: 1}).toArray(), [{_id: 0}]);
- assert.commandWorked(sessionColl.update({_id: 0}, {$set: {inTxn: 1}}));
- assert.commandWorked(session.commitTransaction_forTesting());
-
- // Make sure data is visible after commit.
- assert.docEq(sessionColl.find().sort({_id: 1}).toArray(), [{_id: 0, inTxn: 1}]);
-
- // Check the replica set.
- rollbackTest.stop();
-
+'use strict';
+
+load("jstests/replsets/libs/rollback_test.js");
+
+let name = "transactions_after_rollback_via_refetch";
+let dbName = name;
+let crudCollName = "crudColl";
+let collToDropName = "collToDrop";
+
+let CommonOps = (node) => {
+ // Insert a couple of documents that will initially be present on all nodes.
+ let crudColl = node.getDB(dbName)[crudCollName];
+ assert.commandWorked(crudColl.insert({_id: 0}));
+ assert.commandWorked(crudColl.insert({_id: 1}));
+
+ // Create a collection so it can be dropped on the rollback node.
+ node.getDB(dbName)[collToDropName].insert({_id: 0});
+};
+
+// We want to have the rollback node perform some inserts, updates, and deletes locally
+// during the rollback process, so we can ensure that transactions will read correct data
+// post-rollback, even though these writes will be un-timestamped.
+let RollbackOps = (node) => {
+ let crudColl = node.getDB(dbName)[crudCollName];
+ // Roll back an update (causes refetch and local update).
+ assert.commandWorked(crudColl.update({_id: 0}, {$set: {rollbackNode: 0}}));
+ // Roll back a delete (causes refetch and local insert).
+ assert.commandWorked(crudColl.remove({_id: 1}));
+ // Roll back an insert (causes local delete).
+ assert.commandWorked(crudColl.insert({_id: 2}));
+
+ // Roll back a drop (re-creates the collection).
+ node.getDB(dbName)[collToDropName].drop();
+};
+
+let SyncSourceOps = (node) => {
+ let coll = node.getDB(dbName)[crudCollName];
+ // Update these docs so the rollback node will refetch them.
+ assert.commandWorked(coll.update({_id: 0}, {$set: {syncSource: 0}}));
+ assert.commandWorked(coll.update({_id: 1}, {$set: {syncSource: 1}}));
+};
+
+// Set up a replica set for use in RollbackTest. We disable majority reads on all nodes so that
+// they will use the "rollbackViaRefetch" algorithm.
+let replTest = new ReplSetTest({
+ name,
+ nodes: 3,
+ useBridge: true,
+ settings: {chainingAllowed: false},
+ nodeOptions: {enableMajorityReadConcern: "false"}
+});
+replTest.startSet();
+let config = replTest.getReplSetConfig();
+config.members[2].priority = 0;
+replTest.initiate(config);
+
+let rollbackTest = new RollbackTest(name, replTest);
+
+CommonOps(rollbackTest.getPrimary());
+
+let rollbackNode = rollbackTest.transitionToRollbackOperations();
+RollbackOps(rollbackNode);
+
+let syncSourceNode = rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
+SyncSourceOps(syncSourceNode);
+
+// Wait for rollback to finish.
+rollbackTest.transitionToSyncSourceOperationsDuringRollback();
+rollbackTest.transitionToSteadyStateOperations();
+
+// Make the rollback node primary so we can run transactions against it.
+rollbackTest.getTestFixture().stepUp(rollbackNode);
+
+jsTestLog("Testing transactions against the node that just rolled back.");
+const sessionOptions = {
+ causalConsistency: false
+};
+let session = rollbackNode.getDB(dbName).getMongo().startSession(sessionOptions);
+let sessionDb = session.getDatabase(dbName);
+let sessionColl = sessionDb[crudCollName];
+
+// Make sure we can do basic CRUD ops inside a transaction and read the data back correctly, pre
+// and post-commit.
+session.startTransaction();
+// Make sure we read from the snapshot correctly.
+assert.docEq(sessionColl.find().sort({_id: 1}).toArray(),
+ [{_id: 0, syncSource: 0}, {_id: 1, syncSource: 1}]);
+// Do some basic ops.
+assert.commandWorked(sessionColl.update({_id: 0}, {$set: {inTxn: 1}}));
+assert.commandWorked(sessionColl.remove({_id: 1}));
+assert.commandWorked(sessionColl.insert({_id: 2}));
+// Make sure we read the updated data correctly.
+assert.docEq(sessionColl.find().sort({_id: 1}).toArray(),
+ [{_id: 0, syncSource: 0, inTxn: 1}, {_id: 2}]);
+assert.commandWorked(session.commitTransaction_forTesting());
+
+// Make sure data is visible after commit.
+assert.docEq(sessionColl.find().sort({_id: 1}).toArray(),
+ [{_id: 0, syncSource: 0, inTxn: 1}, {_id: 2}]);
+
+// Run a transaction that touches the collection that was re-created during rollback.
+sessionColl = sessionDb[collToDropName];
+session.startTransaction();
+assert.docEq(sessionColl.find().sort({_id: 1}).toArray(), [{_id: 0}]);
+assert.commandWorked(sessionColl.update({_id: 0}, {$set: {inTxn: 1}}));
+assert.commandWorked(session.commitTransaction_forTesting());
+
+// Make sure data is visible after commit.
+assert.docEq(sessionColl.find().sort({_id: 1}).toArray(), [{_id: 0, inTxn: 1}]);
+
+// Check the replica set.
+rollbackTest.stop();
}());