summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommaso Tocci <tommaso.tocci@mongodb.com>2023-08-30 08:23:29 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-08-30 08:49:07 +0000
commit4fad44a858d8ee2d642566fc8872ef410f6534e4 (patch)
treef7b4397330b7615561fd00dd7ae5ba3a8c610c22
parenta52145092eeae0d03897a898c3e3e57ff49c35d2 (diff)
SERVER-80488 Avoid traversing routing table in balancer split chunk policyr5.0.21-rc0r5.0.21
-rw-r--r--src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp72
-rw-r--r--src/mongo/db/s/balancer/balancer_policy.cpp12
-rw-r--r--src/mongo/db/s/balancer/balancer_policy.h9
-rw-r--r--src/mongo/db/s/balancer/balancer_policy_test.cpp206
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_zone_operations.cpp6
5 files changed, 166 insertions, 139 deletions
diff --git a/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp b/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp
index 6af2597ffd2..8371a27b950 100644
--- a/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp
+++ b/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp
@@ -57,6 +57,30 @@ using SplitInfoVector = BalancerChunkSelectionPolicy::SplitInfoVector;
namespace {
+StatusWith<ZoneInfo> createCollectionZoneInfo(OperationContext* opCtx,
+ const NamespaceString& nss,
+ const KeyPattern& keyPattern) {
+ ZoneInfo zoneInfo;
+ const auto swCollectionTags =
+ Grid::get(opCtx)->catalogClient()->getTagsForCollection(opCtx, nss);
+ if (!swCollectionTags.isOK()) {
+ return swCollectionTags.getStatus().withContext(
+ str::stream() << "Unable to load tags for collection " << nss);
+ }
+ const auto& collectionTags = swCollectionTags.getValue();
+
+ for (const auto& tag : collectionTags) {
+ auto status =
+ zoneInfo.addRangeToZone(ZoneRange{keyPattern.extendRangeBound(tag.getMinKey(), false),
+ keyPattern.extendRangeBound(tag.getMaxKey(), false),
+ tag.getTag()});
+ if (!status.isOK()) {
+ return status;
+ }
+ }
+ return {std::move(zoneInfo)};
+}
+
/**
* Does a linear pass over the information cached in the specified chunk manager and extracts chunk
* distribution and chunk placement information which is needed by the balancer policy.
@@ -88,31 +112,13 @@ StatusWith<DistributionStatus> createCollectionDistributionStatus(
return true;
});
- const auto swCollectionTags =
- Grid::get(opCtx)->catalogClient()->getTagsForCollection(opCtx, nss);
- if (!swCollectionTags.isOK()) {
- return swCollectionTags.getStatus().withContext(
- str::stream() << "Unable to load tags for collection " << nss);
- }
- const auto& collectionTags = swCollectionTags.getValue();
-
- DistributionStatus distribution(nss, std::move(shardToChunksMap));
-
- // Cache the collection tags
- const auto& keyPattern = chunkMgr.getShardKeyPattern().getKeyPattern();
-
- for (const auto& tag : collectionTags) {
- auto status = distribution.addRangeToZone(
- ZoneRange(keyPattern.extendRangeBound(tag.getMinKey(), false),
- keyPattern.extendRangeBound(tag.getMaxKey(), false),
- tag.getTag()));
-
- if (!status.isOK()) {
- return status;
- }
+ auto swZoneInfo =
+ createCollectionZoneInfo(opCtx, nss, chunkMgr.getShardKeyPattern().getKeyPattern());
+ if (!swZoneInfo.isOK()) {
+ return swZoneInfo.getStatus();
}
- return {std::move(distribution)};
+ return {DistributionStatus{nss, std::move(shardToChunksMap), std::move(swZoneInfo.getValue())}};
}
/**
@@ -183,12 +189,12 @@ private:
* range boundaries.
*/
void getSplitCandidatesToEnforceTagRanges(const ChunkManager& cm,
- const DistributionStatus& distribution,
+ const ZoneInfo& zoneInfo,
SplitCandidatesBuffer* splitCandidates) {
const auto& globalMax = cm.getShardKeyPattern().getKeyPattern().globalMax();
// For each tag range, find chunks that need to be split.
- for (const auto& tagRangeEntry : distribution.tagRanges()) {
+ for (const auto& tagRangeEntry : zoneInfo.zoneRanges()) {
const auto& tagRange = tagRangeEntry.second;
const auto chunkAtZoneMin = cm.findIntersectingChunkWithSimpleCollation(tagRange.min);
@@ -533,26 +539,26 @@ StatusWith<SplitInfoVector> BalancerChunkSelectionPolicyImpl::_getSplitCandidate
const auto& cm = routingInfoStatus.getValue();
- const auto collInfoStatus = createCollectionDistributionStatus(opCtx, nss, shardStats, cm);
- if (!collInfoStatus.isOK()) {
- return collInfoStatus.getStatus();
+ const auto swCollZoneInfo =
+ createCollectionZoneInfo(opCtx, nss, cm.getShardKeyPattern().getKeyPattern());
+ if (!swCollZoneInfo.isOK()) {
+ return swCollZoneInfo.getStatus();
}
-
- const DistributionStatus& distribution = collInfoStatus.getValue();
+ const auto& collZoneInfo = swCollZoneInfo.getValue();
// Accumulate split points for the same chunk together
SplitCandidatesBuffer splitCandidates(nss, cm.getVersion());
if (nss == NamespaceString::kLogicalSessionsNamespace) {
- if (!distribution.tags().empty()) {
+ if (!collZoneInfo.allZones().empty()) {
LOGV2_WARNING(4562401,
"Ignoring zones for the sessions collection",
- "tags"_attr = distribution.tags());
+ "tags"_attr = collZoneInfo.allZones());
}
getSplitCandidatesForSessionsCollection(opCtx, cm, &splitCandidates);
} else {
- getSplitCandidatesToEnforceTagRanges(cm, distribution, &splitCandidates);
+ getSplitCandidatesToEnforceTagRanges(cm, collZoneInfo, &splitCandidates);
}
return splitCandidates.done();
diff --git a/src/mongo/db/s/balancer/balancer_policy.cpp b/src/mongo/db/s/balancer/balancer_policy.cpp
index b632f1d79d8..ec4041b9667 100644
--- a/src/mongo/db/s/balancer/balancer_policy.cpp
+++ b/src/mongo/db/s/balancer/balancer_policy.cpp
@@ -60,8 +60,12 @@ const size_t kDefaultImbalanceThreshold = 1;
} // namespace
-DistributionStatus::DistributionStatus(NamespaceString nss, ShardToChunksMap shardToChunksMap)
- : _nss(std::move(nss)), _shardChunks(std::move(shardToChunksMap)) {}
+DistributionStatus::DistributionStatus(NamespaceString nss,
+ ShardToChunksMap shardToChunksMap,
+ ZoneInfo zoneInfo)
+ : _nss(std::move(nss)),
+ _shardChunks(std::move(shardToChunksMap)),
+ _zoneInfo(std::move(zoneInfo)) {}
size_t DistributionStatus::totalChunks() const {
size_t total = 0;
@@ -110,10 +114,6 @@ const vector<ChunkType>& DistributionStatus::getChunks(const ShardId& shardId) c
return i->second;
}
-Status DistributionStatus::addRangeToZone(const ZoneRange& range) {
- return _zoneInfo.addRangeToZone(range);
-}
-
string DistributionStatus::getTagForChunk(const ChunkType& chunk) const {
return _zoneInfo.getZoneForChunk(chunk.getRange());
}
diff --git a/src/mongo/db/s/balancer/balancer_policy.h b/src/mongo/db/s/balancer/balancer_policy.h
index 2b685b79bbb..b8403c3881f 100644
--- a/src/mongo/db/s/balancer/balancer_policy.h
+++ b/src/mongo/db/s/balancer/balancer_policy.h
@@ -86,6 +86,7 @@ typedef std::map<ShardId, std::vector<ChunkType>> ShardToChunksMap;
class ZoneInfo {
public:
ZoneInfo();
+ ZoneInfo(ZoneInfo&&) = default;
/**
* Appends the specified range to the set of ranges tracked for this collection and checks if
@@ -131,7 +132,7 @@ class DistributionStatus {
DistributionStatus& operator=(const DistributionStatus&) = delete;
public:
- DistributionStatus(NamespaceString nss, ShardToChunksMap shardToChunksMap);
+ DistributionStatus(NamespaceString nss, ShardToChunksMap shardToChunksMap, ZoneInfo zoneInfo);
DistributionStatus(DistributionStatus&&) = default;
/**
@@ -142,12 +143,6 @@ public:
}
/**
- * Appends the specified range to the set of ranges tracked for this collection and checks if
- * it overlaps with existing ranges.
- */
- Status addRangeToZone(const ZoneRange& range);
-
- /**
* Returns total number of chunks across all shards.
*/
size_t totalChunks() const;
diff --git a/src/mongo/db/s/balancer/balancer_policy_test.cpp b/src/mongo/db/s/balancer/balancer_policy_test.cpp
index 7d0c56e72ae..8f3b340c82d 100644
--- a/src/mongo/db/s/balancer/balancer_policy_test.cpp
+++ b/src/mongo/db/s/balancer/balancer_policy_test.cpp
@@ -130,8 +130,8 @@ TEST(BalancerPolicy, Basic) {
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId2, kNoMaxSize, 3, false, emptyTagSet, emptyShardVersion), 3}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -146,8 +146,8 @@ TEST(BalancerPolicy, SmallClusterShouldBePerfectlyBalanced) {
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId1, migrations[0].from);
ASSERT_EQ(kShardId2, migrations[0].to);
@@ -161,10 +161,13 @@ TEST(BalancerPolicy, SingleChunkShouldNotMove) {
{{ShardStatistics(kShardId0, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- ASSERT(balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), true, false)
- .empty());
ASSERT(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false)
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), true, false)
+ .empty());
+ ASSERT(
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false)
.empty());
}
@@ -175,10 +178,13 @@ TEST(BalancerPolicy, BalanceThresholdObeyed) {
{ShardStatistics(kShardId2, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId3, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1}});
- ASSERT(balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), true, false)
- .empty());
ASSERT(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false)
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), true, false)
+ .empty());
+ ASSERT(
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false)
.empty());
}
@@ -189,8 +195,8 @@ TEST(BalancerPolicy, ParallelBalancing) {
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -215,8 +221,8 @@ TEST(BalancerPolicy, ParallelBalancingDoesNotPutChunksOnShardsAboveTheOptimal) {
{ShardStatistics(kShardId4, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId5, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -239,8 +245,8 @@ TEST(BalancerPolicy, ParallelBalancingDoesNotMoveChunksFromShardsBelowOptimal) {
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 5},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -259,8 +265,11 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNe
// Here kShardId0 would have been selected as a donor
stdx::unordered_set<ShardId> availableShards{kShardId1, kShardId2, kShardId3};
- const auto migrations(BalancerPolicy::balance(
- cluster.first, DistributionStatus(kNamespace, cluster.second), &availableShards, false));
+ const auto migrations(
+ BalancerPolicy::balance(cluster.first,
+ DistributionStatus(kNamespace, cluster.second, ZoneInfo()),
+ &availableShards,
+ false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId1, migrations[0].from);
@@ -279,8 +288,11 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNo
// Here kShardId0 would have been selected as a donor
stdx::unordered_set<ShardId> availableShards{kShardId1, kShardId2, kShardId3};
- const auto migrations(BalancerPolicy::balance(
- cluster.first, DistributionStatus(kNamespace, cluster.second), &availableShards, false));
+ const auto migrations(
+ BalancerPolicy::balance(cluster.first,
+ DistributionStatus(kNamespace, cluster.second, ZoneInfo()),
+ &availableShards,
+ false));
ASSERT_EQ(0U, migrations.size());
}
@@ -293,8 +305,11 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseDestinationShards) {
// Here kShardId2 would have been selected as a recipient
stdx::unordered_set<ShardId> availableShards{kShardId0, kShardId1, kShardId3};
- const auto migrations(BalancerPolicy::balance(
- cluster.first, DistributionStatus(kNamespace, cluster.second), &availableShards, false));
+ const auto migrations(
+ BalancerPolicy::balance(cluster.first,
+ DistributionStatus(kNamespace, cluster.second, ZoneInfo()),
+ &availableShards,
+ false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -314,8 +329,8 @@ TEST(BalancerPolicy, JumboChunksNotMoved) {
cluster.second[kShardId0][2].setJumbo(true);
cluster.second[kShardId0][3].setJumbo(true);
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -341,8 +356,8 @@ TEST(BalancerPolicy, JumboChunksNotMovedParallel) {
cluster.second[kShardId2][2].setJumbo(false); // Only chunk 1 is not jumbo
cluster.second[kShardId2][3].setJumbo(true);
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -364,8 +379,8 @@ TEST(BalancerPolicy, DrainingSingleChunk) {
{{ShardStatistics(kShardId0, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -382,8 +397,8 @@ TEST(BalancerPolicy, DrainingSingleChunkPerShard) {
{ShardStatistics(kShardId2, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -405,8 +420,8 @@ TEST(BalancerPolicy, DrainingWithTwoChunksFirstOneSelected) {
{{ShardStatistics(kShardId0, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -423,8 +438,8 @@ TEST(BalancerPolicy, DrainingMultipleShardsFirstOneSelected) {
{ShardStatistics(kShardId1, kNoMaxSize, 5, true, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 16}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId2, migrations[0].to);
@@ -440,8 +455,8 @@ TEST(BalancerPolicy, DrainingMultipleShardsWontAcceptChunks) {
{ShardStatistics(kShardId1, kNoMaxSize, 0, true, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId2, kNoMaxSize, 0, true, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT(migrations.empty());
}
@@ -451,9 +466,10 @@ TEST(BalancerPolicy, DrainingSingleAppropriateShardFoundDueToTag) {
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, {"LAX"}, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 1, true, {"LAX"}, emptyShardVersion), 1}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(
cluster.second[kShardId2][0].getMin(), cluster.second[kShardId2][0].getMax(), "LAX")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -470,9 +486,10 @@ TEST(BalancerPolicy, DrainingNoAppropriateShardsFoundDueToTag) {
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, {"LAX"}, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 1, true, {"SEA"}, emptyShardVersion), 1}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(
cluster.second[kShardId2][0].getMin(), cluster.second[kShardId2][0].getMax(), "SEA")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT(migrations.empty());
@@ -485,8 +502,8 @@ TEST(BalancerPolicy, NoBalancingDueToAllNodesEitherDrainingOrMaxedOut) {
{ShardStatistics(kShardId1, 1, 1, false, emptyTagSet, emptyShardVersion), 6},
{ShardStatistics(kShardId2, kNoMaxSize, 1, true, emptyTagSet, emptyShardVersion), 1}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT(migrations.empty());
}
@@ -499,8 +516,8 @@ TEST(BalancerPolicy, BalancerRespectsMaxShardSizeOnlyBalanceToNonMaxed) {
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 5},
{ShardStatistics(kShardId2, kNoMaxSize, 10, false, emptyTagSet, emptyShardVersion), 10}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId2, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -517,8 +534,8 @@ TEST(BalancerPolicy, BalancerRespectsMaxShardSizeWhenAllBalanced) {
{ShardStatistics(kShardId1, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4}});
- const auto migrations(
- balanceChunks(cluster.first, DistributionStatus(kNamespace, cluster.second), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT(migrations.empty());
}
@@ -529,9 +546,10 @@ TEST(BalancerPolicy, BalancerRespectsTagsWhenDraining) {
{ShardStatistics(kShardId1, kNoMaxSize, 5, true, {"a", "b"}, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, {"b"}, emptyShardVersion), 2}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 7), "a")));
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(BSON("x" << 8), kMaxBSONKey, "b")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 7), "a")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 8), kMaxBSONKey, "b")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -550,8 +568,9 @@ TEST(BalancerPolicy, BalancerRespectsTagPolicyBeforeImbalance) {
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 6},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 100), "a")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 100), "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -570,9 +589,10 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsWithCrossShardViolationOfTags) {
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, {"b"}, emptyShardVersion), 3}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "b")));
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(BSON("x" << 8), kMaxBSONKey, "a")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "b")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 8), kMaxBSONKey, "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -590,8 +610,9 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedCluster) {
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 10), "a")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 10), "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -608,8 +629,9 @@ TEST(BalancerPolicy, BalancerTagAlreadyBalanced) {
{{ShardStatistics(kShardId0, kNoMaxSize, 3, false, {"a"}, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, {"a"}, emptyShardVersion), 2}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, kMaxBSONKey, "a")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, kMaxBSONKey, "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
ASSERT(balanceChunks(cluster.first, distribution, false, false).empty());
}
@@ -621,10 +643,11 @@ TEST(BalancerPolicy, BalancerMostOverLoadShardHasMultipleTags) {
{ShardStatistics(kShardId1, kNoMaxSize, 1, false, {"b"}, emptyShardVersion), 1},
{ShardStatistics(kShardId2, kNoMaxSize, 1, false, {"c"}, emptyShardVersion), 1}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "a")));
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 3), "b")));
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(BSON("x" << 3), BSON("x" << 5), "c")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "a")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 3), "b")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 3), BSON("x" << 5), "c")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -644,10 +667,11 @@ TEST(BalancerPolicy, BalancerMostOverLoadShardHasMultipleTagsSkipTagWithShardInU
{ShardStatistics(kShardId1, kNoMaxSize, 1, false, {"b"}, emptyShardVersion), 1},
{ShardStatistics(kShardId2, kNoMaxSize, 1, false, {"c"}, emptyShardVersion), 1}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "a")));
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 3), "b")));
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(BSON("x" << 3), BSON("x" << 5), "c")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "a")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 3), "b")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 3), BSON("x" << 5), "c")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
stdx::unordered_set<ShardId> availableShards{kShardId0, kShardId2, kShardId3};
const auto migrations(
@@ -668,8 +692,9 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedClusterParalle
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3},
{ShardStatistics(kShardId3, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 20), "a")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 20), "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(2U, migrations.size());
@@ -692,42 +717,42 @@ TEST(BalancerPolicy, BalancerHandlesNoShardsWithTag) {
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2}});
- DistributionStatus distribution(kNamespace, cluster.second);
- ASSERT_OK(
- distribution.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 7), "NonExistentZone")));
+ ZoneInfo zoneInfo;
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 7), "NonExistentZone")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
ASSERT(balanceChunks(cluster.first, distribution, false, false).empty());
}
TEST(DistributionStatus, AddTagRangeOverlap) {
- DistributionStatus d(kNamespace, ShardToChunksMap{});
+ ZoneInfo zInfo;
// Note that there is gap between 10 and 20 for which there is no tag
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "a")));
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << 20), BSON("x" << 30), "b")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "a")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 20), BSON("x" << 30), "b")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 2), "d")));
+ zInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 2), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(BSON("x" << -1), BSON("x" << 5), "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << -1), BSON("x" << 5), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(BSON("x" << 5), BSON("x" << 9), "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << 5), BSON("x" << 9), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(BSON("x" << 5), BSON("x" << 25), "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << 5), BSON("x" << 25), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(BSON("x" << -1), BSON("x" << 32), "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << -1), BSON("x" << 32), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- d.addRangeToZone(ZoneRange(BSON("x" << 25), kMaxBSONKey, "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << 25), kMaxBSONKey, "d")));
}
TEST(DistributionStatus, ChunkTagsSelectorWithRegularKeys) {
- DistributionStatus d(kNamespace, ShardToChunksMap{});
-
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "a")));
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << 10), BSON("x" << 20), "b")));
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << 20), BSON("x" << 30), "c")));
+ ZoneInfo zInfo;
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "a")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 10), BSON("x" << 20), "b")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 20), BSON("x" << 30), "c")));
+ DistributionStatus d(kNamespace, ShardToChunksMap{}, std::move(zInfo));
{
ChunkType chunk;
@@ -794,11 +819,12 @@ TEST(DistributionStatus, ChunkTagsSelectorWithRegularKeys) {
}
TEST(DistributionStatus, ChunkTagsSelectorWithMinMaxKeys) {
- DistributionStatus d(kNamespace, ShardToChunksMap{});
- ASSERT_OK(d.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << -100), "a")));
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << -10), BSON("x" << 10), "b")));
- ASSERT_OK(d.addRangeToZone(ZoneRange(BSON("x" << 100), kMaxBSONKey, "c")));
+ ZoneInfo zInfo;
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << -100), "a")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << -10), BSON("x" << 10), "b")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 100), kMaxBSONKey, "c")));
+ DistributionStatus d(kNamespace, ShardToChunksMap{}, std::move(zInfo));
{
ChunkType chunk;
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_zone_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_zone_operations.cpp
index a9a19dc7a41..c0c4b36eeb0 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_zone_operations.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_zone_operations.cpp
@@ -66,7 +66,7 @@ Status checkForOverlappingZonedKeyRange(OperationContext* opCtx,
const ChunkRange& range,
const std::string& zoneName,
const KeyPattern& shardKeyPattern) {
- DistributionStatus chunkDist(nss, ShardToChunksMap{});
+ ZoneInfo zoneInfo;
auto tagStatus = configServer->exhaustiveFindOnConfig(opCtx,
kConfigPrimarySelector,
@@ -89,7 +89,7 @@ Status checkForOverlappingZonedKeyRange(OperationContext* opCtx,
// Always extend ranges to full shard key to be compatible with tags created before
// the zone commands were implemented.
const auto& parsedTagDoc = tagParseStatus.getValue();
- auto overlapStatus = chunkDist.addRangeToZone(
+ auto overlapStatus = zoneInfo.addRangeToZone(
ZoneRange(shardKeyPattern.extendRangeBound(parsedTagDoc.getMinKey(), false),
shardKeyPattern.extendRangeBound(parsedTagDoc.getMaxKey(), false),
parsedTagDoc.getTag()));
@@ -99,7 +99,7 @@ Status checkForOverlappingZonedKeyRange(OperationContext* opCtx,
}
auto overlapStatus =
- chunkDist.addRangeToZone(ZoneRange(range.getMin(), range.getMax(), zoneName));
+ zoneInfo.addRangeToZone(ZoneRange(range.getMin(), range.getMax(), zoneName));
if (!overlapStatus.isOK()) {
return overlapStatus;
}