summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Noma <gregory.noma@gmail.com>2020-04-23 13:25:12 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-23 17:45:50 +0000
commit96d26475d7fb4ff6937c75b822b8ab573b63f860 (patch)
treeb962f4641f87866de021ee1c5e2077f62b735d13
parenta7206698e24a77abdcf2d1edae718a822a947d98 (diff)
downloadmongo-96d26475d7fb4ff6937c75b822b8ab573b63f860.tar.gz
SERVER-46487 Add fast path to getShardIdsForRange() when chunk range is [MinKey, MaxKey]
(cherry picked from commit d9d92a15561dc84223d302475e09d0fa91309550)
-rw-r--r--src/mongo/s/chunk_manager.cpp27
-rw-r--r--src/mongo/s/chunk_manager_refresh_bm.cpp24
2 files changed, 46 insertions, 5 deletions
diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp
index 1b61b34be59..bd8a4cf2e72 100644
--- a/src/mongo/s/chunk_manager.cpp
+++ b/src/mongo/s/chunk_manager.cpp
@@ -50,12 +50,19 @@ namespace {
// Used to generate sequence numbers to assign to each newly created RoutingTableHistory
AtomicWord<unsigned> nextCMSequenceNumber(0);
-void checkAllElementsAreOfType(BSONType type, const BSONObj& o) {
- for (auto&& element : o) {
- uassert(ErrorCodes::ConflictingOperationInProgress,
- str::stream() << "Not all elements of " << o << " are of type " << typeName(type),
- element.type() == type);
+bool allElementsAreOfType(BSONType type, const BSONObj& obj) {
+ for (auto&& elem : obj) {
+ if (elem.type() != type) {
+ return false;
+ }
}
+ return true;
+}
+
+void checkAllElementsAreOfType(BSONType type, const BSONObj& o) {
+ uassert(ErrorCodes::ConflictingOperationInProgress,
+ str::stream() << "Not all elements of " << o << " are of type " << typeName(type),
+ allElementsAreOfType(type, o));
}
std::string extractKeyStringInternal(const BSONObj& shardKeyValue, Ordering ordering) {
@@ -194,6 +201,16 @@ void ChunkManager::getShardIdsForQuery(OperationContext* opCtx,
void ChunkManager::getShardIdsForRange(const BSONObj& min,
const BSONObj& max,
std::set<ShardId>* shardIds) const {
+ // If our range is [MinKey, MaxKey], we can simply return all shard ids right away. However,
+ // this optimization does not apply when we are reading from a snapshot because _shardVersions
+ // contains shards with chunks and is built based on the last refresh. Therefore, it is
+ // possible for _shardVersions to have fewer entries if a shard no longer owns chunks when it
+ // used to at _clusterTime.
+ if (!_clusterTime && allElementsAreOfType(MinKey, min) && allElementsAreOfType(MaxKey, max)) {
+ getAllShardIds(shardIds);
+ return;
+ }
+
const auto bounds = _rt->overlappingRanges(min, max, true);
for (auto it = bounds.first; it != bounds.second; ++it) {
shardIds->insert(it->second->getShardIdAt(_clusterTime));
diff --git a/src/mongo/s/chunk_manager_refresh_bm.cpp b/src/mongo/s/chunk_manager_refresh_bm.cpp
index 3e02667abf6..b1303e07456 100644
--- a/src/mongo/s/chunk_manager_refresh_bm.cpp
+++ b/src/mongo/s/chunk_manager_refresh_bm.cpp
@@ -268,6 +268,24 @@ void BM_GetShardIdsForRange(benchmark::State& state,
}
template <typename CollectionMetadataBuilderFn>
+void BM_GetShardIdsForRangeMinKeyToMaxKey(benchmark::State& state,
+ CollectionMetadataBuilderFn makeCollectionMetadata) {
+ const int nShards = state.range(0);
+ const int nChunks = state.range(1);
+
+ auto cm = makeCollectionMetadata(nShards, nChunks);
+ auto min = BSON("_id" << MINKEY);
+ auto max = BSON("_id" << MAXKEY);
+
+ for (auto keepRunning : state) {
+ std::set<ShardId> shardIds;
+ cm->getChunkManager()->getShardIdsForRange(min, max, &shardIds);
+ }
+
+ state.SetItemsProcessed(state.iterations());
+}
+
+template <typename CollectionMetadataBuilderFn>
void BM_KeyBelongsToMe(benchmark::State& state,
CollectionMetadataBuilderFn makeCollectionMetadata) {
const int nShards = state.range(0);
@@ -332,6 +350,12 @@ MONGO_INITIALIZER(RegisterBenchmarks)(InitializerContext* context) {
BM_GetShardIdsForRange, Pessimal, makeChunkManagerWithPessimalBalancedDistribution),
REGISTER_BENCHMARK_CAPTURE(
BM_GetShardIdsForRange, Optimal, makeChunkManagerWithOptimalBalancedDistribution),
+ REGISTER_BENCHMARK_CAPTURE(BM_GetShardIdsForRangeMinKeyToMaxKey,
+ Pessimal,
+ makeChunkManagerWithPessimalBalancedDistribution),
+ REGISTER_BENCHMARK_CAPTURE(BM_GetShardIdsForRangeMinKeyToMaxKey,
+ Optimal,
+ makeChunkManagerWithOptimalBalancedDistribution),
REGISTER_BENCHMARK_CAPTURE(
BM_KeyBelongsToMe, Pessimal, makeChunkManagerWithPessimalBalancedDistribution),
REGISTER_BENCHMARK_CAPTURE(