diff options
author | Pierlauro Sciarelli <pierlauro.sciarelli@mongodb.com> | 2023-01-09 07:40:09 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-01-09 08:20:38 +0000 |
commit | 4a948883cdff5003b215857244251179334c6ef7 (patch) | |
tree | d5125d791d8ce7ef817718ed4c4d612b7a873cd7 | |
parent | 8d7e9163ec0f6e224b033445fd94c9839ee4504c (diff) | |
download | mongo-4a948883cdff5003b215857244251179334c6ef7.tar.gz |
SERVER-71609 `splitOrMarkJumbo` must not over-split chunks
-rw-r--r-- | src/mongo/db/s/auto_split_vector_command.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/s/config/sharding_catalog_manager_chunk_operations.cpp | 12 | ||||
-rw-r--r-- | src/mongo/s/request_types/auto_split_vector.idl | 4 | ||||
-rw-r--r-- | src/mongo/s/shard_util.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/shard_util.h | 16 |
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 |