Files
mongo/jstests/sharding/chunks_onCurrentShardSince.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

139 lines
4.6 KiB
JavaScript

/**
* Tests that `onCurrentShardSince` is always consistent with `history[0].validAfter` on
* config.chunks entries
*/
import {ShardingTest} from "jstests/libs/shardingtest.js";
Random.setRandomSeed();
/* Perform up to 'maxNumSplits' random chunk splits */
function performRandomSplitChunks(st, collFullName, maxNumSplits) {
for (let i = 0; i < maxNumSplits; i++) {
// pick a random split point between -50000 and 50000
const splitPoint = Math.floor(Math.random() * 100000 - 50000);
if (st.config.chunks.find({"min": {x: NumberLong(splitPoint)}}).count() != 0) {
continue;
}
assert.commandWorked(st.s.adminCommand({split: collFullName, middle: {x: NumberLong(splitPoint)}}));
}
}
/* Create new sharded collection on testDB with up to 201 initial chunks*/
let _collCounter = 0;
function newShardedColl(st, testDB) {
const coll = testDB["coll_" + _collCounter++];
assert.commandWorked(
st.s.adminCommand({
shardCollection: coll.getFullName(),
key: {x: "hashed"},
}),
);
// Perform up to 200 chunk splits
performRandomSplitChunks(st, coll.getFullName(), 200);
return coll;
}
/* Perform up to 5 random chunk moves */
function performRandomMoveChunks(st, collFullName) {
const collUuid = st.s.getDB("config").collections.findOne({_id: collFullName}).uuid;
function getOppositeShard(shardName) {
if (shardName === st.shard0.shardName) {
return st.shard1.shardName;
} else {
return st.shard0.shardName;
}
}
const numMoves = Math.floor(Math.random() * 5);
for (let i = 0; i < numMoves; i++) {
const chunks = st.config.chunks.find({"uuid": collUuid}).sort({min: 1}).toArray();
const chunk = chunks[Math.floor(Math.random() * chunks.length)];
assert.commandWorked(
st.s.adminCommand({moveChunk: collFullName, find: chunk.min, to: getOppositeShard(chunk.shard)}),
);
}
}
/* Verifies that `onCurrentShardSince` is set and it has the same value as
* `history[0].validAfter` for each chunk
*/
function assertChunksConsistency(chunksColl) {
const numTotalChunks = chunksColl.find().count();
assert.neq(0, numTotalChunks);
const numConsistenChunks = chunksColl
.find({
$and: [
{"onCurrentShardSince": {$exists: 1}},
{
$expr: {
$eq: ["$onCurrentShardSince", {$getField: {field: "validAfter", input: {$first: "$history"}}}],
},
},
],
})
.count();
assert.eq(numTotalChunks, numConsistenChunks);
}
function moveAndMergeChunksTest(st, testDB) {
const coll = newShardedColl(st, testDB);
const collUuid = st.s.getDB("config").collections.findOne({_id: coll.getFullName()}).uuid;
// Perform some random moves to have different values on `onCurrentShardSince` fields
performRandomMoveChunks(st, coll.getFullName());
assertChunksConsistency(st.config.chunks);
// Perform at most 10 random merges
for (let i = 0; i < 10; i++) {
const chunks = st.config.chunks.find({"uuid": collUuid}).sort({min: 1}).toArray();
const firstChunkToMergeIndex = Math.floor(Math.random() * (chunks.length - 3));
const firstChunk = chunks[firstChunkToMergeIndex];
let lastChunkToMergeIndex = firstChunkToMergeIndex;
for (let j = 0; j < 3; j++) {
if (chunks[lastChunkToMergeIndex + 1].shard !== firstChunk.shard) {
break;
}
lastChunkToMergeIndex++;
}
if (firstChunkToMergeIndex === lastChunkToMergeIndex) {
continue;
}
const lastChunk = chunks[lastChunkToMergeIndex];
assert.commandWorked(
st.s.adminCommand({mergeChunks: coll.getFullName(), bounds: [firstChunk.min, lastChunk.max]}),
);
}
assertChunksConsistency(st.config.chunks);
}
function splitChunksTest(st, testDB) {
const coll = newShardedColl(st, testDB);
// Perform some random moves to have different values on `onCurrentShardSince` fields
performRandomMoveChunks(st, coll.getFullName());
assertChunksConsistency(st.config.chunks);
// Perform at most 10 random splits
performRandomSplitChunks(st, coll.getFullName(), 10);
assertChunksConsistency(st.config.chunks);
}
/* Test setup */
const st = new ShardingTest({mongos: 1, shards: 2});
const testDB = st.s.getDB(jsTestName());
/* Perform tests */
if (!TestData.configShard) {
moveAndMergeChunksTest(st, testDB);
splitChunksTest(st, testDB);
}
st.stop();