summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierlauro Sciarelli <pierlauro.sciarelli@mongodb.com>2023-01-09 07:40:09 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-01-09 08:20:38 +0000
commit4a948883cdff5003b215857244251179334c6ef7 (patch)
treed5125d791d8ce7ef817718ed4c4d612b7a873cd7
parent8d7e9163ec0f6e224b033445fd94c9839ee4504c (diff)
downloadmongo-4a948883cdff5003b215857244251179334c6ef7.tar.gz
SERVER-71609 `splitOrMarkJumbo` must not over-split chunks
-rw-r--r--src/mongo/db/s/auto_split_vector_command.cpp3
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_chunk_operations.cpp12
-rw-r--r--src/mongo/s/request_types/auto_split_vector.idl4
-rw-r--r--src/mongo/s/shard_util.cpp6
-rw-r--r--src/mongo/s/shard_util.h16
5 files changed, 28 insertions, 13 deletions
diff --git a/src/mongo/db/s/auto_split_vector_command.cpp b/src/mongo/db/s/auto_split_vector_command.cpp
index 18cdbd9cef6..dc4effd9b15 100644
--- a/src/mongo/db/s/auto_split_vector_command.cpp
+++ b/src/mongo/db/s/auto_split_vector_command.cpp
@@ -87,7 +87,8 @@ public:
req.getKeyPattern(),
req.getMin(),
req.getMax(),
- req.getMaxChunkSizeBytes());
+ req.getMaxChunkSizeBytes(),
+ req.getLimit());
Response autoSplitVectorResponse(std::move(splitPoints));
autoSplitVectorResponse.setContinuation(continuation);
return autoSplitVectorResponse;
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_chunk_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_chunk_operations.cpp
index f9f33a065d2..edd6087a9af 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_chunk_operations.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_chunk_operations.cpp
@@ -1792,13 +1792,18 @@ void ShardingCatalogManager::splitOrMarkJumbo(OperationContext* opCtx,
Grid::get(opCtx)->getBalancerConfiguration()->getMaxChunkSizeBytes());
}();
- const auto splitPoints = uassertStatusOK(
+ // Limit the search to one split point: this code path is reached when a migration fails due
+ // to ErrorCodes::ChunkTooBig. In case there is a too frequent shard key, only select the
+ // next key in order to split the range in jumbo chunk + remaining range.
+ const int limit = 1;
+ auto splitPoints = uassertStatusOK(
shardutil::selectChunkSplitPoints(opCtx,
chunk.getShardId(),
nss,
cm.getShardKeyPattern(),
ChunkRange(chunk.getMin(), chunk.getMax()),
- maxChunkSizeBytes));
+ maxChunkSizeBytes,
+ limit));
if (splitPoints.empty()) {
LOGV2(21873,
@@ -1852,6 +1857,9 @@ void ShardingCatalogManager::splitOrMarkJumbo(OperationContext* opCtx,
return;
}
+ // Resize the vector because in multiversion scenarios the `autoSplitVector` command may end
+ // up ignoring the `limit` parameter and returning the whole list of split points.
+ splitPoints.resize(limit);
uassertStatusOK(
shardutil::splitChunkAtMultiplePoints(opCtx,
chunk.getShardId(),
diff --git a/src/mongo/s/request_types/auto_split_vector.idl b/src/mongo/s/request_types/auto_split_vector.idl
index abcbece2019..3e55eb01d8e 100644
--- a/src/mongo/s/request_types/auto_split_vector.idl
+++ b/src/mongo/s/request_types/auto_split_vector.idl
@@ -75,3 +75,7 @@ commands:
maxChunkSizeBytes:
type: safeInt64
description: "Max chunk size of the collection expressed in bytes"
+ limit:
+ type: int
+ description: "Max number of split points to look for"
+ optional: true
diff --git a/src/mongo/s/shard_util.cpp b/src/mongo/s/shard_util.cpp
index ae5e1aa9a1b..62ee76524ea 100644
--- a/src/mongo/s/shard_util.cpp
+++ b/src/mongo/s/shard_util.cpp
@@ -132,7 +132,8 @@ StatusWith<std::vector<BSONObj>> selectChunkSplitPoints(OperationContext* opCtx,
const NamespaceString& nss,
const ShardKeyPattern& shardKeyPattern,
const ChunkRange& chunkRange,
- long long chunkSizeBytes) {
+ long long chunkSizeBytes,
+ boost::optional<int> limit) {
auto shardStatus = Grid::get(opCtx)->shardRegistry()->getShard(opCtx, shardId);
if (!shardStatus.isOK()) {
return shardStatus.getStatus();
@@ -147,8 +148,9 @@ StatusWith<std::vector<BSONObj>> selectChunkSplitPoints(OperationContext* opCtx,
Shard::RetryPolicy::kIdempotent);
};
- const AutoSplitVectorRequest req(
+ AutoSplitVectorRequest req(
nss, shardKeyPattern.toBSON(), chunkRange.getMin(), chunkRange.getMax(), chunkSizeBytes);
+ req.setLimit(limit);
auto cmdStatus = invokeSplitCommand(req.toBSON({}), nss.db());
diff --git a/src/mongo/s/shard_util.h b/src/mongo/s/shard_util.h
index 997dcc1e4c9..18eb780eb1e 100644
--- a/src/mongo/s/shard_util.h
+++ b/src/mongo/s/shard_util.h
@@ -79,20 +79,20 @@ StatusWith<long long> retrieveCollectionShardSize(OperationContext* opCtx,
/**
* Ask the specified shard to figure out the split points for a given chunk.
*
- * shardId The shard id to query.
- * nss Namespace, which owns the chunk.
- * shardKeyPattern The shard key which corresponds to this sharded namespace.
- * chunkRange Bounds of the chunk to be split.
- * chunkSize Chunk size to target in bytes.
- * maxObjs Limits the number of objects in each chunk. Zero means max, unspecified means use the
- * server default.
+ * - shardId: the shard id to query.
+ * - nss: namespace, which owns the chunk.
+ * - shardKeyPattern: the shard key which corresponds to this sharded namespace.
+ * - chunkRange: bounds of the chunk to search for split points on.
+ * - chunkSizeBytes: chunk size to target in bytes.
+ * - limit: limits the number of split points to search. Unspecified means no limit
*/
StatusWith<std::vector<BSONObj>> selectChunkSplitPoints(OperationContext* opCtx,
const ShardId& shardId,
const NamespaceString& nss,
const ShardKeyPattern& shardKeyPattern,
const ChunkRange& chunkRange,
- long long chunkSizeBytes);
+ long long chunkSizeBytes,
+ boost::optional<int> limit = boost::none);
/**
* Asks the specified shard to split the chunk described by min/maxKey into the respective split