summaryrefslogtreecommitdiff
path: root/jstests/sharding/transactions_snapshot_errors_first_statement.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/sharding/transactions_snapshot_errors_first_statement.js')
-rw-r--r--jstests/sharding/transactions_snapshot_errors_first_statement.js272
1 files changed, 135 insertions, 137 deletions
diff --git a/jstests/sharding/transactions_snapshot_errors_first_statement.js b/jstests/sharding/transactions_snapshot_errors_first_statement.js
index 2d915425033..3b0f5f74953 100644
--- a/jstests/sharding/transactions_snapshot_errors_first_statement.js
+++ b/jstests/sharding/transactions_snapshot_errors_first_statement.js
@@ -8,159 +8,157 @@
//
// @tags: [requires_sharding, uses_transactions, uses_multi_shard_transaction]
(function() {
- "use strict";
-
- load("jstests/sharding/libs/sharded_transactions_helpers.js");
-
- const dbName = "test";
- const collName = "foo";
- const ns = dbName + '.' + collName;
-
- const kCommandTestCases = [
- {name: "aggregate", command: {aggregate: collName, pipeline: [], cursor: {}}},
- {name: "distinct", command: {distinct: collName, query: {}, key: "_id"}},
- {name: "find", command: {find: collName}},
- {
- // findAndModify can only target one shard, even in the two shard case.
- name: "findAndModify",
- command: {findAndModify: collName, query: {_id: 1}, update: {$set: {x: 1}}}
- },
- {name: "insert", command: {insert: collName, documents: [{_id: 1}, {_id: 11}]}},
- {
- name: "update",
- command: {
- update: collName,
- updates: [{q: {_id: 1}, u: {$set: {_id: 2}}}, {q: {_id: 11}, u: {$set: {_id: 12}}}]
- }
- },
- {
- name: "delete",
- command:
- {delete: collName, deletes: [{q: {_id: 2}, limit: 1}, {q: {_id: 12}, limit: 1}]}
- },
- // We cannot test killCursors because mongos discards the response from any killCursors
- // requests that may be sent to shards.
- ];
-
- // Verify that all commands that can start a transaction are able to retry on snapshot errors.
- function runTest(st, collName, numShardsToError, errorCode, isSharded) {
- const session = st.s.startSession();
- const sessionDB = session.getDatabase(dbName);
-
- for (let commandTestCase of kCommandTestCases) {
- const commandName = commandTestCase.name;
- const commandBody = commandTestCase.command;
-
- if (isSharded && commandName === "distinct") {
- // Distinct isn't allowed on sharded collections in a multi-document transaction.
- print("Skipping distinct test case for sharded collection");
- continue;
- }
-
- //
- // Retry on a single error.
- //
-
- setFailCommandOnShards(st, {times: 1}, [commandName], errorCode, numShardsToError);
-
- session.startTransaction({readConcern: {level: "snapshot"}});
- assert.commandWorked(sessionDB.runCommand(commandBody));
-
- assert.commandWorked(session.commitTransaction_forTesting());
-
- unsetFailCommandOnEachShard(st, numShardsToError);
-
- // Clean up after insert to avoid duplicate key errors.
- if (commandName === "insert") {
- assert.writeOK(sessionDB[collName].remove({_id: {$in: [1, 11]}}));
- }
-
- //
- // Retry on multiple errors.
- //
-
- setFailCommandOnShards(st, {times: 3}, [commandName], errorCode, numShardsToError);
-
- session.startTransaction({readConcern: {level: "snapshot"}});
- assert.commandWorked(sessionDB.runCommand(commandBody));
-
- assert.commandWorked(session.commitTransaction_forTesting());
-
- unsetFailCommandOnEachShard(st, numShardsToError);
-
- // Clean up after insert to avoid duplicate key errors.
- if (commandName === "insert") {
- assert.writeOK(sessionDB[collName].remove({_id: {$in: [1, 11]}}));
- }
-
- //
- // Exhaust retry attempts.
- //
-
- setFailCommandOnShards(st, "alwaysOn", [commandName], errorCode, numShardsToError);
-
- session.startTransaction({readConcern: {level: "snapshot"}});
- const res = assert.commandFailedWithCode(sessionDB.runCommand(commandBody), errorCode);
- assert.eq(res.errorLabels, ["TransientTransactionError"]);
-
- unsetFailCommandOnEachShard(st, numShardsToError);
-
- assertNoSuchTransactionOnAllShards(
- st, session.getSessionId(), session.getTxnNumber_forTesting());
-
- assert.commandFailedWithCode(session.abortTransaction_forTesting(),
- ErrorCodes.NoSuchTransaction);
+"use strict";
+
+load("jstests/sharding/libs/sharded_transactions_helpers.js");
+
+const dbName = "test";
+const collName = "foo";
+const ns = dbName + '.' + collName;
+
+const kCommandTestCases = [
+ {name: "aggregate", command: {aggregate: collName, pipeline: [], cursor: {}}},
+ {name: "distinct", command: {distinct: collName, query: {}, key: "_id"}},
+ {name: "find", command: {find: collName}},
+ {
+ // findAndModify can only target one shard, even in the two shard case.
+ name: "findAndModify",
+ command: {findAndModify: collName, query: {_id: 1}, update: {$set: {x: 1}}}
+ },
+ {name: "insert", command: {insert: collName, documents: [{_id: 1}, {_id: 11}]}},
+ {
+ name: "update",
+ command: {
+ update: collName,
+ updates: [{q: {_id: 1}, u: {$set: {_id: 2}}}, {q: {_id: 11}, u: {$set: {_id: 12}}}]
+ }
+ },
+ {
+ name: "delete",
+ command: {delete: collName, deletes: [{q: {_id: 2}, limit: 1}, {q: {_id: 12}, limit: 1}]}
+ },
+ // We cannot test killCursors because mongos discards the response from any killCursors
+ // requests that may be sent to shards.
+];
+
+// Verify that all commands that can start a transaction are able to retry on snapshot errors.
+function runTest(st, collName, numShardsToError, errorCode, isSharded) {
+ const session = st.s.startSession();
+ const sessionDB = session.getDatabase(dbName);
+
+ for (let commandTestCase of kCommandTestCases) {
+ const commandName = commandTestCase.name;
+ const commandBody = commandTestCase.command;
+
+ if (isSharded && commandName === "distinct") {
+ // Distinct isn't allowed on sharded collections in a multi-document transaction.
+ print("Skipping distinct test case for sharded collection");
+ continue;
}
- }
- const st = new ShardingTest({shards: 2, mongos: 1, config: 1});
+ //
+ // Retry on a single error.
+ //
- enableStaleVersionAndSnapshotRetriesWithinTransactions(st);
+ setFailCommandOnShards(st, {times: 1}, [commandName], errorCode, numShardsToError);
- jsTestLog("Unsharded transaction");
+ session.startTransaction({readConcern: {level: "snapshot"}});
+ assert.commandWorked(sessionDB.runCommand(commandBody));
- assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 5}, {writeConcern: {w: "majority"}}));
- st.ensurePrimaryShard(dbName, st.shard0.shardName);
+ assert.commandWorked(session.commitTransaction_forTesting());
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, 1, errorCode, false /* isSharded */);
- }
+ unsetFailCommandOnEachShard(st, numShardsToError);
- // Enable sharding and set up 2 chunks, [minKey, 10), [10, maxKey), each with one document
- // (includes the document already inserted).
- assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
- st.ensurePrimaryShard(dbName, st.shard0.shardName);
- assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {_id: 1}}));
+ // Clean up after insert to avoid duplicate key errors.
+ if (commandName === "insert") {
+ assert.writeOK(sessionDB[collName].remove({_id: {$in: [1, 11]}}));
+ }
- assert.commandWorked(st.s.adminCommand({split: ns, middle: {_id: 10}}));
- assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 15}, {writeConcern: {w: "majority"}}));
+ //
+ // Retry on multiple errors.
+ //
- jsTestLog("One shard sharded transaction");
+ setFailCommandOnShards(st, {times: 3}, [commandName], errorCode, numShardsToError);
- assert.eq(2, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
- assert.eq(0, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard1.shardName}));
+ session.startTransaction({readConcern: {level: "snapshot"}});
+ assert.commandWorked(sessionDB.runCommand(commandBody));
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, 1, errorCode, true /* isSharded */);
- }
+ assert.commandWorked(session.commitTransaction_forTesting());
- jsTestLog("Two shard sharded transaction");
+ unsetFailCommandOnEachShard(st, numShardsToError);
- assert.commandWorked(
- st.s.adminCommand({moveChunk: ns, find: {_id: 15}, to: st.shard1.shardName}));
- assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
- assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
+ // Clean up after insert to avoid duplicate key errors.
+ if (commandName === "insert") {
+ assert.writeOK(sessionDB[collName].remove({_id: {$in: [1, 11]}}));
+ }
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, 2, errorCode, true /* isSharded */);
- }
+ //
+ // Exhaust retry attempts.
+ //
- // Test only one shard throwing the error when more than one are targeted.
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, 1, errorCode, true /* isSharded */);
+ setFailCommandOnShards(st, "alwaysOn", [commandName], errorCode, numShardsToError);
+
+ session.startTransaction({readConcern: {level: "snapshot"}});
+ const res = assert.commandFailedWithCode(sessionDB.runCommand(commandBody), errorCode);
+ assert.eq(res.errorLabels, ["TransientTransactionError"]);
+
+ unsetFailCommandOnEachShard(st, numShardsToError);
+
+ assertNoSuchTransactionOnAllShards(
+ st, session.getSessionId(), session.getTxnNumber_forTesting());
+
+ assert.commandFailedWithCode(session.abortTransaction_forTesting(),
+ ErrorCodes.NoSuchTransaction);
}
+}
+
+const st = new ShardingTest({shards: 2, mongos: 1, config: 1});
+
+enableStaleVersionAndSnapshotRetriesWithinTransactions(st);
+
+jsTestLog("Unsharded transaction");
+
+assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 5}, {writeConcern: {w: "majority"}}));
+st.ensurePrimaryShard(dbName, st.shard0.shardName);
+
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, 1, errorCode, false /* isSharded */);
+}
+
+// Enable sharding and set up 2 chunks, [minKey, 10), [10, maxKey), each with one document
+// (includes the document already inserted).
+assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
+st.ensurePrimaryShard(dbName, st.shard0.shardName);
+assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {_id: 1}}));
+
+assert.commandWorked(st.s.adminCommand({split: ns, middle: {_id: 10}}));
+assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 15}, {writeConcern: {w: "majority"}}));
+
+jsTestLog("One shard sharded transaction");
+
+assert.eq(2, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
+assert.eq(0, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard1.shardName}));
+
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, 1, errorCode, true /* isSharded */);
+}
+
+jsTestLog("Two shard sharded transaction");
+
+assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {_id: 15}, to: st.shard1.shardName}));
+assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
+assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
+
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, 2, errorCode, true /* isSharded */);
+}
+
+// Test only one shard throwing the error when more than one are targeted.
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, 1, errorCode, true /* isSharded */);
+}
- disableStaleVersionAndSnapshotRetriesWithinTransactions(st);
+disableStaleVersionAndSnapshotRetriesWithinTransactions(st);
- st.stop();
+st.stop();
})();