mongo/jstests/sharding/resharding_min_fetch_ts_wit...

87 lines
3.3 KiB
JavaScript

/**
* Test to make sure that if there are uncommitted transactions right when the resharding command
* begins, it will select a cloneTimestamp that is greater than the operation time of those
* transactions when they commit.
*
* @tags: [uses_atclustertime]
*/
import {ReshardingTest} from "jstests/sharding/libs/resharding_test_fixture.js";
const reshardingTest = new ReshardingTest({numDonors: 2, numRecipients: 2, reshardInPlace: true});
reshardingTest.setup();
const donorShardNames = reshardingTest.donorShardNames;
const sourceCollection = reshardingTest.createShardedCollection({
ns: "reshardingDb.coll",
shardKeyPattern: {oldKey: 1},
chunks: [
{min: {oldKey: MinKey}, max: {oldKey: 10}, shard: donorShardNames[0]},
{min: {oldKey: 10}, max: {oldKey: MaxKey}, shard: donorShardNames[1]},
],
});
const mongos = sourceCollection.getMongo();
const session = mongos.startSession({causalConsistency: false, retryWrites: false});
const sessionCollection = session
.getDatabase(sourceCollection.getDB().getName())
.getCollection(sourceCollection.getName());
assert.commandWorked(sessionCollection.insert({_id: 0, oldKey: 5, newKey: 15, counter: 0}));
session.startTransaction();
assert.commandWorked(sessionCollection.update({_id: 0, oldKey: 5}, {$inc: {counter: 1}}));
const recipientShardNames = reshardingTest.recipientShardNames;
reshardingTest.withReshardingInBackground(
{
newShardKeyPattern: {newKey: 1},
newChunks: [
{min: {newKey: MinKey}, max: {newKey: 10}, shard: recipientShardNames[0]},
{min: {newKey: 10}, max: {newKey: MaxKey}, shard: recipientShardNames[1]},
],
},
() => {
// Make sure that the resharding donor service will be blocked waiting for the MODE_S lock
// for the collection being resharded because of a transaction that started prior to the
// resharding command. Once we confirmed this, we can let the transaction commit and allow
// the resharding command to complete.
assert.soon(() => {
let curOpOpt = {idleSessions: false, allUsers: true, idleConnections: true};
let matchStage = {$match: {"locks.Collection": "R", desc: /ReshardingDonorService/}};
let curOpResults = mongos
.getDB("admin")
.aggregate([{$currentOp: curOpOpt}, matchStage])
.toArray();
return curOpResults.length > 0;
});
let coordinatorDoc = mongos.getCollection("config.reshardingOperations").findOne({
ns: sourceCollection.getFullName(),
});
assert.neq(null, coordinatorDoc);
assert.eq(undefined, coordinatorDoc.cloneTimestamp);
let res = assert.commandWorked(session.commitTransaction_forTesting());
let commitOperationTS = res.operationTime;
assert.soon(() => {
coordinatorDoc = mongos.getCollection("config.reshardingOperations").findOne({
ns: sourceCollection.getFullName(),
});
return coordinatorDoc !== null && coordinatorDoc.cloneTimestamp !== undefined;
});
assert.eq(
1,
timestampCmp(coordinatorDoc.cloneTimestamp, commitOperationTS),
"coordinatorDoc: " + tojson(coordinatorDoc) + ", commit opTs: " + tojson(commitOperationTS),
);
},
);
reshardingTest.teardown();