mirror of https://github.com/mongodb/mongo
87 lines
3.3 KiB
JavaScript
87 lines
3.3 KiB
JavaScript
// Test that ensuring index existence (createIndexes on an existing index) successfully runs in a
|
|
// cross-shard transaction and that attempting to do createIndexes when only a subset of shards is
|
|
// aware of the existing index fails.
|
|
//
|
|
// @tags: [
|
|
// requires_sharding,
|
|
// uses_multi_shard_transaction,
|
|
// uses_transactions,
|
|
// ]
|
|
import {withAbortAndRetryOnTransientTxnError} from "jstests/libs/auto_retry_transaction_in_sharding.js";
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
|
|
const dbName = "TestDB";
|
|
const collName = "foo";
|
|
const ns = dbName + "." + collName;
|
|
|
|
const st = new ShardingTest({
|
|
shards: 2,
|
|
mongos: 1,
|
|
});
|
|
|
|
// Set up one sharded collection with 2 chunks distributd across 2 shards
|
|
assert.commandWorked(st.enableSharding(dbName, st.shard0.shardName));
|
|
assert.commandWorked(
|
|
st.s.getDB(dbName).runCommand({
|
|
createIndexes: collName,
|
|
indexes: [{key: {a: 1}, name: "a_1"}],
|
|
writeConcern: {w: "majority"},
|
|
}),
|
|
);
|
|
|
|
assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {_id: 1}}));
|
|
assert.commandWorked(st.s.adminCommand({split: ns, middle: {_id: 0}}));
|
|
assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {_id: 5}, to: st.shard1.shardName}));
|
|
|
|
assert.commandWorked(st.s.getDB(dbName)[collName].insert({_id: -5}, {writeConcern: {w: "majority"}}));
|
|
assert.commandWorked(st.s.getDB(dbName)[collName].insert({_id: 5}, {writeConcern: {w: "majority"}}));
|
|
|
|
const session = st.s.getDB(dbName).getMongo().startSession({causalConsistency: false});
|
|
let sessionDB = session.getDatabase(dbName);
|
|
let sessionColl = sessionDB[collName];
|
|
|
|
{
|
|
jsTest.log("Testing createIndexes on an existing index in a transaction");
|
|
withAbortAndRetryOnTransientTxnError(session, () => {
|
|
session.startTransaction({writeConcern: {w: "majority"}});
|
|
|
|
assert.commandWorked(sessionColl.runCommand({createIndexes: collName, indexes: [{key: {a: 1}, name: "a_1"}]}));
|
|
// Perform cross-shard writes to execute prepare path.
|
|
assert.commandWorked(sessionColl.insert({_id: -1, m: -1}));
|
|
assert.commandWorked(sessionColl.insert({_id: +1, m: +1}));
|
|
assert.eq(-1, sessionColl.findOne({m: -1})._id);
|
|
assert.eq(+1, sessionColl.findOne({m: +1})._id);
|
|
|
|
session.commitTransaction();
|
|
});
|
|
}
|
|
{
|
|
jsTest.log(
|
|
"Testing createIndexes on an existing index in a transaction when not all shards are" +
|
|
" aware of that index (should abort)",
|
|
);
|
|
|
|
// Simulate a scenario where one shard with chunks for a collection is unaware of one of the
|
|
// collection's indexes
|
|
assert.commandWorked(st.shard1.getDB(dbName).getCollection(collName).dropIndexes("a_1"));
|
|
|
|
withAbortAndRetryOnTransientTxnError(session, () => {
|
|
session.startTransaction({writeConcern: {w: "majority"}});
|
|
|
|
assert.commandFailedWithCode(
|
|
sessionColl.runCommand({createIndexes: collName, indexes: [{key: {a: 1}, name: "a_1"}]}),
|
|
ErrorCodes.OperationNotSupportedInTransaction,
|
|
);
|
|
});
|
|
|
|
assert.commandFailedWithCode(session.abortTransaction_forTesting(), ErrorCodes.NoSuchTransaction);
|
|
}
|
|
|
|
// Resolve index inconsistency to pass consistency checks.
|
|
st.shard1
|
|
.getDB(dbName)
|
|
.getCollection(collName)
|
|
.runCommand({createIndexes: collName, indexes: [{key: {a: 1}, name: "a_1"}]});
|
|
|
|
st.stop();
|