Files
mongo/jstests/sharding/updateOne_with_id_without_shard_key_basic.js
Zac 591928c619 SERVER-108478 JS formatted by prettier and remove clang-format (#39656)
GitOrigin-RevId: 6c8f6aded47f260aa4f7c231b17dae3302cb1e04
2025-08-21 17:27:09 +00:00

132 lines
4.0 KiB
JavaScript

/**
* Tests updateOne with id without shard key uses PM-3190 for retryable
* writes and doesn't for transactions or non-retryable writes.
*
* @tags: [requires_fcv_80]
*/
import {
withRetryOnTransientTxnErrorIncrementTxnNum,
withTxnAndAutoRetryOnMongos,
} from "jstests/libs/auto_retry_transaction_in_sharding.js";
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
import {funWithArgs} from "jstests/libs/parallel_shell_helpers.js";
import {ShardingTest} from "jstests/libs/shardingtest.js";
import {CreateShardedCollectionUtil} from "jstests/sharding/libs/create_sharded_collection_util.js";
const st = new ShardingTest({shards: 2, mongos: 1});
const mongos = st.s0;
let db = mongos.getDB(jsTestName());
const coll = db.coll;
coll.drop();
CreateShardedCollectionUtil.shardCollectionWithChunks(coll, {x: 1}, [
{min: {x: MinKey}, max: {x: 0}, shard: st.shard0.shardName},
{min: {x: 0}, max: {x: MaxKey}, shard: st.shard1.shardName},
]);
// Write two documents.
assert.commandWorked(coll.insert({x: -1, _id: -1}));
assert.commandWorked(coll.insert({x: 1, _id: 1}));
let fp = configureFailPoint(st.s, "hangAfterCompletingWriteWithoutShardKeyWithId");
// Test that transactions do not use broadcast protocol per PM-3190.
let session = st.s.startSession({retryWrites: false});
withTxnAndAutoRetryOnMongos(session, () => {
let sessionColl = session.getDatabase(db.getName()).getCollection(coll.getName());
let updateCmd = {
updates: [{q: {_id: -1}, u: {$inc: {counter: 1}}}],
txnNumber: NumberLong(0),
};
assert.commandWorked(sessionColl.runCommand("update", updateCmd));
});
session.endSession();
// Test that retryable internal transactions do not use broadcast protocol per PM-3190.
const lsidWithUUID = {
id: UUID(),
txnUUID: UUID(),
};
let txnNumber = 1;
withRetryOnTransientTxnErrorIncrementTxnNum(txnNumber, (txnNum) => {
assert.commandWorked(
db.runCommand({
update: coll.getName(),
updates: [{q: {_id: -1}, u: {$inc: {counter: 1}}}],
lsid: lsidWithUUID,
txnNumber: NumberLong(txnNum),
startTransaction: true,
autocommit: false,
}),
);
});
const lsidWithUUIDAndTxnNum = {
id: UUID(),
txnUUID: UUID(),
txnNumber: NumberLong(2),
};
txnNumber = 1;
withRetryOnTransientTxnErrorIncrementTxnNum(txnNumber, (txnNum) => {
assert.commandWorked(
db.runCommand({
update: coll.getName(),
updates: [{q: {_id: -5}, u: {$inc: {counter: 1}}}],
lsid: lsidWithUUIDAndTxnNum,
txnNumber: NumberLong(txnNum),
startTransaction: true,
autocommit: false,
}),
);
});
// Test that non-retryable writes do not use broadcast protocol per PM-3190.
assert.commandWorked(coll.updateOne({_id: 1}, {$inc: {counter: 1}}));
// Test that non-retryable write sessions do not use broadcast protocol per PM-3190.
session = st.s.startSession({retryWrites: false});
let sessionColl = session.getDatabase(db.getName()).getCollection(coll.getName());
let updateCmd = {
updates: [{q: {_id: 1}, u: {$inc: {counter: 1}}}],
};
assert.commandWorked(sessionColl.runCommand("update", updateCmd));
session.endSession();
// Test that retryable writes use broadcast protocol per PM-3190
session = st.s.startSession({retryWrites: true});
const lsid = session.getSessionId();
const joinUpdate = startParallelShell(
funWithArgs(
function (dbName, collName, lsid) {
assert.commandWorked(
db
.getSiblingDB(dbName)
.getCollection(collName)
.runCommand("update", {
updates: [{q: {_id: 1}, u: {$inc: {counter: 1}}}],
lsid: lsid,
txnNumber: NumberLong(5),
}),
);
},
db.getName(),
coll.getName(),
lsid,
),
mongos.port,
);
// We should hit the configured failpoint if PM-3190 code is used.
fp.wait();
fp.off();
joinUpdate();
session.endSession();
st.stop();