SERVER-108097 Review responsibilities and uses of migration utility (#39038)

GitOrigin-RevId: 09c962f8f77e7e6d1c3e3e57bb3962268178ba7b
This commit is contained in:
Antonio Fuschetto 2025-07-24 21:49:22 +02:00 committed by MongoDB Bot
parent 8e9958a377
commit 7cabe18f42
8 changed files with 50 additions and 49 deletions

View File

@ -158,7 +158,6 @@
#include "mongo/db/s/ddl_lock_manager.h"
#include "mongo/db/s/migration_blocking_operation/multi_update_coordinator.h"
#include "mongo/db/s/migration_chunk_cloner_source_op_observer.h"
#include "mongo/db/s/migration_util.h"
#include "mongo/db/s/periodic_replica_set_configshard_maintenance_mode_checker.h"
#include "mongo/db/s/periodic_sharded_index_consistency_checker.h"
#include "mongo/db/s/query_analysis_op_observer_configsvr.h"
@ -235,6 +234,7 @@
#include "mongo/s/resource_yielders.h"
#include "mongo/s/routing_information_cache.h"
#include "mongo/s/service_entry_point_router_role.h"
#include "mongo/s/sharding_feature_flags_gen.h"
#include "mongo/scripting/dbdirectclient_factory.h"
#include "mongo/scripting/engine.h"
#include "mongo/stdx/mutex.h"

View File

@ -30,6 +30,7 @@
#include "mongo/db/s/metadata_manager.h"
#include "mongo/db/s/migration_util.h"
#include "mongo/db/s/shard_key_util.h"
#include "mongo/logv2/log.h"
#include "mongo/s/chunk_manager.h"
@ -53,7 +54,7 @@ bool metadataOverlapsRange(const CollectionMetadata& metadata, const ChunkRange&
return true;
}
auto chunkRangeToCompareToMetadata =
migrationutil::extendOrTruncateBoundsForMetadata(metadata, range);
shardkeyutil::extendOrTruncateBoundsForMetadata(metadata, range);
return metadata.rangeOverlapsChunk(chunkRangeToCompareToMetadata);
}

View File

@ -240,44 +240,6 @@ BSONObj makeMigrationStatusDocumentDestination(
return builder.obj();
}
ChunkRange extendOrTruncateBoundsForMetadata(const CollectionMetadata& metadata,
const ChunkRange& range) {
auto metadataShardKeyPattern = KeyPattern(metadata.getKeyPattern());
// If the input range is shorter than the range in the ChunkManager inside
// 'metadata', we must extend its bounds to get a correct comparison. If the input
// range is longer than the range in the ChunkManager, we likewise must shorten it.
// We make sure to match what's in the ChunkManager instead of the other way around,
// since the ChunkManager only stores ranges and compares overlaps using a string version of the
// key, rather than a BSONObj. This logic is necessary because the _metadata list can
// contain ChunkManagers with different shard keys if the shard key has been refined.
//
// Note that it's safe to use BSONObj::nFields() (which returns the number of top level
// fields in the BSONObj) to compare the two, since shard key refine operations can only add
// top-level fields.
//
// Using extractFieldsUndotted to shorten the input range is correct because the ChunkRange and
// the shard key pattern will both already store nested shard key fields as top-level dotted
// fields, and extractFieldsUndotted uses the top-level fields verbatim rather than treating
// dots as accessors for subfields.
auto metadataShardKeyPatternBson = metadataShardKeyPattern.toBSON();
auto numFieldsInMetadataShardKey = metadataShardKeyPatternBson.nFields();
auto numFieldsInInputRangeShardKey = range.getMin().nFields();
if (numFieldsInInputRangeShardKey < numFieldsInMetadataShardKey) {
auto extendedRangeMin = metadataShardKeyPattern.extendRangeBound(
range.getMin(), false /* makeUpperInclusive */);
auto extendedRangeMax = metadataShardKeyPattern.extendRangeBound(
range.getMax(), false /* makeUpperInclusive */);
return ChunkRange(extendedRangeMin, extendedRangeMax);
} else if (numFieldsInInputRangeShardKey > numFieldsInMetadataShardKey) {
auto shortenedRangeMin = range.getMin().extractFieldsUndotted(metadataShardKeyPatternBson);
auto shortenedRangeMax = range.getMax().extractFieldsUndotted(metadataShardKeyPatternBson);
return ChunkRange(shortenedRangeMin, shortenedRangeMax);
} else {
return range;
}
}
bool deletionTaskUuidMatchesFilteringMetadataUuid(
OperationContext* opCtx,
const boost::optional<mongo::CollectionMetadata>& optCollDescr,

View File

@ -108,13 +108,6 @@ BSONObj makeMigrationStatusDocumentDestination(
const BSONObj& max,
boost::optional<long long> sessionOplogEntriesMigrated);
/**
* Returns a chunk range with extended or truncated boundaries to match the number of fields in the
* given metadata's shard key pattern.
*/
ChunkRange extendOrTruncateBoundsForMetadata(const CollectionMetadata& metadata,
const ChunkRange& range);
/**
* Writes the migration coordinator document to config.migrationCoordinators and waits for majority
* write concern.

View File

@ -47,7 +47,6 @@
#include "mongo/db/repl/wait_for_majority_service.h"
#include "mongo/db/s/collection_metadata.h"
#include "mongo/db/s/collection_sharding_runtime.h"
#include "mongo/db/s/migration_util.h"
#include "mongo/db/s/operation_sharding_state.h"
#include "mongo/db/s/range_deletion_task_gen.h"
#include "mongo/db/s/shard_server_test_fixture.h"

View File

@ -54,6 +54,7 @@
#include "mongo/db/s/read_only_catalog_cache_loader.h"
#include "mongo/db/s/resharding/resharding_donor_recipient_common.h"
#include "mongo/db/s/shard_filtering_util.h"
#include "mongo/db/s/shard_key_util.h"
#include "mongo/db/s/sharding_migration_critical_section.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/db/service_context.h"
@ -603,7 +604,7 @@ void FilteringMetadataCache::_recoverMigrationCoordinations(OperationContext* op
// Note this should only extend the range boundaries (if there has been a shard key
// refine since the migration began) and never truncate them.
auto chunkRangeToCompareToMetadata =
migrationutil::extendOrTruncateBoundsForMetadata(currentMetadata, doc.getRange());
shardkeyutil::extendOrTruncateBoundsForMetadata(currentMetadata, doc.getRange());
if (currentMetadata.keyBelongsToMe(chunkRangeToCompareToMetadata.getMin())) {
coordinator.setMigrationDecision(DecisionEnum::kAborted);
} else {

View File

@ -568,5 +568,43 @@ boost::optional<BSONObj> ValidationBehaviorsReshardingBulkIndex::getShardKeyInde
return _shardKeyIndexSpec;
}
ChunkRange extendOrTruncateBoundsForMetadata(const CollectionMetadata& metadata,
const ChunkRange& range) {
auto metadataShardKeyPattern = KeyPattern(metadata.getKeyPattern());
// If the input range is shorter than the range in the ChunkManager inside
// 'metadata', we must extend its bounds to get a correct comparison. If the input
// range is longer than the range in the ChunkManager, we likewise must shorten it.
// We make sure to match what's in the ChunkManager instead of the other way around,
// since the ChunkManager only stores ranges and compares overlaps using a string version of the
// key, rather than a BSONObj. This logic is necessary because the _metadata list can
// contain ChunkManagers with different shard keys if the shard key has been refined.
//
// Note that it's safe to use BSONObj::nFields() (which returns the number of top level
// fields in the BSONObj) to compare the two, since shard key refine operations can only add
// top-level fields.
//
// Using extractFieldsUndotted to shorten the input range is correct because the ChunkRange and
// the shard key pattern will both already store nested shard key fields as top-level dotted
// fields, and extractFieldsUndotted uses the top-level fields verbatim rather than treating
// dots as accessors for subfields.
auto metadataShardKeyPatternBson = metadataShardKeyPattern.toBSON();
auto numFieldsInMetadataShardKey = metadataShardKeyPatternBson.nFields();
auto numFieldsInInputRangeShardKey = range.getMin().nFields();
if (numFieldsInInputRangeShardKey < numFieldsInMetadataShardKey) {
auto extendedRangeMin = metadataShardKeyPattern.extendRangeBound(
range.getMin(), false /* makeUpperInclusive */);
auto extendedRangeMax = metadataShardKeyPattern.extendRangeBound(
range.getMax(), false /* makeUpperInclusive */);
return ChunkRange(extendedRangeMin, extendedRangeMax);
} else if (numFieldsInInputRangeShardKey > numFieldsInMetadataShardKey) {
auto shortenedRangeMin = range.getMin().extractFieldsUndotted(metadataShardKeyPatternBson);
auto shortenedRangeMax = range.getMax().extractFieldsUndotted(metadataShardKeyPatternBson);
return ChunkRange(shortenedRangeMin, shortenedRangeMax);
} else {
return range;
}
}
} // namespace shardkeyutil
} // namespace mongo

View File

@ -242,5 +242,12 @@ void validateTimeseriesShardKey(StringData timeFieldName,
boost::optional<StringData> metaFieldName,
const BSONObj& shardKeyPattern);
/**
* Returns a chunk range with extended or truncated boundaries to match the number of fields in the
* given metadata's shard key pattern.
*/
ChunkRange extendOrTruncateBoundsForMetadata(const CollectionMetadata& metadata,
const ChunkRange& range);
} // namespace shardkeyutil
} // namespace mongo