135 lines
5.2 KiB
JavaScript
135 lines
5.2 KiB
JavaScript
/**
|
|
* Tests that the balancer should not be moving chunks outside of the active window.
|
|
* The outline of the test goes like this:
|
|
* 1. Disable balancer to make sure that it will not try to move chunk on the setup phase.
|
|
* 2. Setup the sharded collections by splitting it into 16 chunks. Since none of the chunks
|
|
* are being moved, all of them will end up on a single shard.
|
|
* 3. Turn the balancer setting to on and set the active balancing window to a time that is
|
|
* outside of the current time at the same time.
|
|
* 4. Make sure that no chunks have moved for at least one balancing round.
|
|
* 5. Reset the active balancing window to a setting that overlaps the current time and make
|
|
* sure that some chunks are moved.
|
|
*/
|
|
(function() {
|
|
/**
|
|
* Simple representation for wall clock time. Hour and minutes should be integers.
|
|
*/
|
|
var HourAndMinute = function(hour, minutes) {
|
|
return {
|
|
/**
|
|
* Returns a new HourAndMinute object with the amount of hours added.
|
|
* Amount can be negative.
|
|
*/
|
|
addHour: function(amount) {
|
|
var newHour = (hour + amount) % 24;
|
|
if (newHour < 0) {
|
|
newHour += 24;
|
|
}
|
|
|
|
return new HourAndMinute(newHour, minutes);
|
|
},
|
|
|
|
/**
|
|
* Returns a string representation that is compatible with the format for the balancer
|
|
* window settings.
|
|
*/
|
|
toString: function() {
|
|
var minStr = (minutes < 10) ? ('0' + minutes) : ('' + minutes);
|
|
var hourStr = (hour < 10) ? ('0' + hour) : ('' + hour);
|
|
return hourStr + ':' + minStr;
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Waits until at least one balancing round has passed.
|
|
*
|
|
* Note: This relies on the fact that the balancer pings the config.mongos document every round.
|
|
*/
|
|
var waitForAtLeastOneBalanceRound = function(mongosHost, timeoutMS) {
|
|
var mongos = new Mongo(mongosHost);
|
|
var configDB = mongos.getDB('config');
|
|
|
|
// Wait for ts to change twice because:
|
|
// 1st: for start of the balancing round.
|
|
// 2nd: for the start of the next round, which implies that the previous one has ended.
|
|
var waitForTSChangeNTimes = 2;
|
|
var lastPing = new Date(0);
|
|
|
|
assert.soon(function() {
|
|
// Note: The balancer pings twice, once with { waiting: false } at the beginning
|
|
// and another { waiting: true } at the end. Poll for the negative edge since
|
|
// the smallest granurality should be a second, if for some reason the interval
|
|
// became less than a second, it can cause this to miss the negative edge and
|
|
// wake it wait longer than it should.
|
|
var currentPing = configDB.mongos.findOne({ _id: mongosHost, waiting: true });
|
|
if (currentPing == null) {
|
|
return false;
|
|
}
|
|
|
|
if (currentPing.ping.valueOf() != lastPing.valueOf()) {
|
|
waitForTSChangeNTimes--;
|
|
lastPing = currentPing.ping;
|
|
}
|
|
|
|
return waitForTSChangeNTimes <= 0;
|
|
}, 'Timed out waiting for mongos ping to change ' + waitForTSChangeNTimes + ' more times',
|
|
timeoutMS, 500);
|
|
};
|
|
|
|
var st = new ShardingTest({ shards: 2 });
|
|
var configDB = st.s.getDB('config');
|
|
assert.commandWorked(configDB.adminCommand({ configureFailPoint: 'balancerRoundIntervalSetting',
|
|
mode: 'alwaysOn',
|
|
data: { sleepSecs: 1 }}));
|
|
|
|
configDB.adminCommand({ enableSharding: 'test' });
|
|
configDB.adminCommand({ shardCollection: 'test.user', key: { _id: 1 }});
|
|
|
|
// Disable balancer so it will not interfere with the chunk distribution setup.
|
|
st.stopBalancer();
|
|
|
|
for (var x = 0; x < 150; x += 10) {
|
|
configDB.adminCommand({ split: 'test.user', middle: { _id: x }});
|
|
}
|
|
|
|
var shard0Chunks = configDB.chunks.find({ ns: 'test.user', shard: 'shard0000' }).count();
|
|
|
|
var startDate = new Date();
|
|
var hourMinStart = new HourAndMinute(startDate.getHours(), startDate.getMinutes());
|
|
configDB.settings.update({ _id: 'balancer' },
|
|
{
|
|
$set: {
|
|
activeWindow: {
|
|
start: hourMinStart.addHour(-2).toString(),
|
|
stop: hourMinStart.addHour(-1).toString()
|
|
},
|
|
stopped: false
|
|
}
|
|
},
|
|
true);
|
|
|
|
waitForAtLeastOneBalanceRound(st.s.host, 60 * 1000);
|
|
|
|
var shard0ChunksAfter = configDB.chunks.find({ ns: 'test.user', shard: 'shard0000' }).count();
|
|
assert.eq(shard0Chunks, shard0ChunksAfter);
|
|
|
|
configDB.settings.update({ _id: 'balancer' },
|
|
{
|
|
$set: {
|
|
activeWindow: {
|
|
start: hourMinStart.toString(),
|
|
stop: hourMinStart.addHour(2).toString()
|
|
}
|
|
}
|
|
},
|
|
true);
|
|
|
|
waitForAtLeastOneBalanceRound(st.s.host, 60 * 1000);
|
|
|
|
shard0ChunksAfter = configDB.chunks.find({ ns: 'test.user', shard: 'shard0000' }).count();
|
|
assert.neq(shard0Chunks, shard0ChunksAfter);
|
|
|
|
st.stop();
|
|
})();
|