diff options
Diffstat (limited to 'src/mongo')
| -rw-r--r-- | src/mongo/db/s/balancer/balancer_policy.cpp | 24 | ||||
| -rw-r--r-- | src/mongo/db/s/balancer/balancer_policy_test.cpp | 40 |
2 files changed, 58 insertions, 6 deletions
diff --git a/src/mongo/db/s/balancer/balancer_policy.cpp b/src/mongo/db/s/balancer/balancer_policy.cpp index 8ce99f1ee79..eda578d1144 100644 --- a/src/mongo/db/s/balancer/balancer_policy.cpp +++ b/src/mongo/db/s/balancer/balancer_policy.cpp @@ -639,15 +639,27 @@ vector<MigrateInfo> BalancerPolicy::balance(const ShardStatisticsVector& shardSt tagsPlusEmpty.push_back(ZoneInfo::kNoZoneName); for (const auto& tag : tagsPlusEmpty) { - const size_t totalNumberOfChunksWithTag = distribution.totalChunksWithTag(tag); - size_t totalNumberOfShardsWithTag = 0; + const auto totalNumberOfChunksWithTag = [&] { + if (tag == ZoneInfo::kNoZoneName) { + return static_cast<size_t>(distribution.getChunkManager()->numChunks()); + } + return distribution.totalChunksWithTag(tag); + }(); - for (const auto& stat : shardStats) { - if (tag == ZoneInfo::kNoZoneName || stat.shardTags.count(tag)) { - totalNumberOfShardsWithTag++; + const auto totalNumberOfShardsWithTag = [&] { + if (tag == ZoneInfo::kNoZoneName) { + return shardStats.size(); } - } + + size_t numShardsWithTag{0}; + for (const auto& stat : shardStats) { + if (stat.shardTags.count(tag)) { + numShardsWithTag++; + } + } + return numShardsWithTag; + }(); // Skip zones which have no shards assigned to them. This situation is not harmful, but // should not be possible so warn the operator to correct it. diff --git a/src/mongo/db/s/balancer/balancer_policy_test.cpp b/src/mongo/db/s/balancer/balancer_policy_test.cpp index a8a8a65f45e..b66622951c3 100644 --- a/src/mongo/db/s/balancer/balancer_policy_test.cpp +++ b/src/mongo/db/s/balancer/balancer_policy_test.cpp @@ -750,6 +750,46 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedClusterParalle ASSERT_EQ(MigrateInfo::zoneViolation, migrations[0].reason); } +TEST(BalancerPolicy, ChunksInNoZoneSpanOnAllShardsWithEmptyZones) { + // Balanacer is able to move chunks in the noZone to shards with tags + auto [cluster, cm] = generateCluster( + {{ShardStatistics(kShardId0, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}, + {ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 0}}); + + ZoneInfo zoneInfo; + ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 100), kSKeyPattern.globalMax(), "a"))); + const auto distribution = makeDistStatus(cm, std::move(zoneInfo)); + + const auto migrations(balanceChunks(cluster.first, distribution, false, false)); + ASSERT_EQ(1U, migrations.size()); + + ASSERT_EQ(kShardId0, migrations[0].from); + ASSERT_EQ(kShardId1, migrations[0].to); + ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][0].getMin(), migrations[0].minKey); + ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][0].getMax(), migrations[0].maxKey); + ASSERT_EQ(MigrateInfo::chunksImbalance, migrations[0].reason); +} + +TEST(BalancerPolicy, BalancingNoZoneIgnoreTotalShardSize) { + // Shard1 is overloaded and contains: + // [min, 1) [1, 2) [2, 3] -> zone("a") + // [3, 4) [4, 5) [5, 6) -> NoZone + // + // But it won't donate any chunk since the + auto [cluster, cm] = generateCluster( + {{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3}, + {ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 6}, + {ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}}); + + ZoneInfo zoneInfo; + ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 6), "a"))); + const auto distribution = makeDistStatus(cm, std::move(zoneInfo)); + + const auto migrations(balanceChunks(cluster.first, distribution, false, false)); + ASSERT_EQ(0U, migrations.size()); +} + + TEST(BalancerPolicy, BalancerHandlesNoShardsWithTag) { auto [cluster, cm] = generateCluster( {{ShardStatistics(kShardId0, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2}, |
