mirror of https://github.com/mongodb/mongo
97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
/**
|
|
* Tests retryability on mongos commands within transactions.
|
|
*
|
|
* @tags: [
|
|
* requires_fcv_83,
|
|
* ]
|
|
*/
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
|
|
const setCommandToFailOnce = (nodeConnection, command, namespace) => {
|
|
return nodeConnection.adminCommand({
|
|
configureFailPoint: "failCommand",
|
|
mode: {times: 1},
|
|
data: {
|
|
errorCode: ErrorCodes.InterruptedDueToReplStateChange,
|
|
failCommands: [command],
|
|
namespace,
|
|
failInternalCommands: true,
|
|
},
|
|
});
|
|
};
|
|
|
|
const kDbName = "testDb";
|
|
const kCollName = "testColl";
|
|
const kNs = `${kDbName}.${kCollName}`;
|
|
|
|
const kDoc0 = {
|
|
_id: 0,
|
|
};
|
|
const kDoc1 = {
|
|
_id: 1,
|
|
};
|
|
|
|
let transactionNumber = 1;
|
|
|
|
const st = new ShardingTest({
|
|
mongos: 1,
|
|
shards: 1,
|
|
rs: {nodes: 1},
|
|
});
|
|
|
|
// Initializes test and inserts dummy document
|
|
jsTest.log("Inserting test document.");
|
|
const mongosDB = st.s0.startSession().getDatabase(kDbName);
|
|
const primaryConnection = st.rs0.getPrimary();
|
|
|
|
assert.commandWorked(
|
|
mongosDB.runCommand({
|
|
insert: kCollName,
|
|
documents: [kDoc0],
|
|
}),
|
|
);
|
|
|
|
// Set the failCommand failpoint to make the next 'find' command fail once due to a failover.
|
|
// Start a transaction & execute a find command.
|
|
// It should succeed since the command will be retried.
|
|
jsTest.log("Testing that mongos retries read commands with startTransaction=true on replication set failover.");
|
|
assert.commandWorked(setCommandToFailOnce(primaryConnection, "find", kNs));
|
|
|
|
assert.commandWorked(
|
|
mongosDB.runCommand({
|
|
find: kCollName,
|
|
filter: kDoc0,
|
|
startTransaction: true,
|
|
txnNumber: NumberLong(transactionNumber++),
|
|
stmtId: NumberInt(0),
|
|
autocommit: false,
|
|
}),
|
|
);
|
|
|
|
// Set the failCommand failpoint to make the next 'update' command fail once due to a failover.
|
|
// Start a transaction & execute a find command.
|
|
// It should fail once due to the 'failCommand' failpoint and should not be retried.
|
|
jsTest.log("Testing that mongos doesn't retry writes with startTransaction=true on replication set failover.");
|
|
assert.commandWorked(setCommandToFailOnce(primaryConnection, "update", kNs));
|
|
|
|
assert.commandFailedWithCode(
|
|
mongosDB.runCommand({
|
|
update: kCollName,
|
|
updates: [{q: kDoc0, u: {$set: {a: 1}}}],
|
|
startTransaction: true,
|
|
txnNumber: NumberLong(transactionNumber++),
|
|
stmtId: NumberInt(0),
|
|
autocommit: false,
|
|
}),
|
|
ErrorCodes.doMongosRewrite(st.s0, ErrorCodes.InterruptedDueToReplStateChange),
|
|
);
|
|
|
|
jsTest.log("Testing that mongos retries retryable writes on failover.");
|
|
assert.commandWorked(setCommandToFailOnce(primaryConnection, "insert", kNs));
|
|
|
|
assert.commandWorked(
|
|
mongosDB.runCommand({insert: kCollName, documents: [kDoc1], txnNumber: NumberLong(transactionNumber++)}),
|
|
);
|
|
|
|
st.stop();
|