mirror of https://github.com/mongodb/mongo
SERVER-114267 Use scatterGatherVersionedTargetByRoutingTable in RefineCollectionShardKeyCoordinator (#44788)
GitOrigin-RevId: 5b611ec8406a4f6ec53b61dfeef7a5b716b9dcef
This commit is contained in:
parent
beb2aa10a4
commit
012d77a858
|
|
@ -45,6 +45,7 @@
|
||||||
#include "mongo/db/global_catalog/ddl/sharding_util.h"
|
#include "mongo/db/global_catalog/ddl/sharding_util.h"
|
||||||
#include "mongo/db/namespace_string.h"
|
#include "mongo/db/namespace_string.h"
|
||||||
#include "mongo/db/op_observer/op_observer.h"
|
#include "mongo/db/op_observer/op_observer.h"
|
||||||
|
#include "mongo/db/router_role/cluster_commands_helpers.h"
|
||||||
#include "mongo/db/router_role/router_role.h"
|
#include "mongo/db/router_role/router_role.h"
|
||||||
#include "mongo/db/shard_role/lock_manager/exception_util.h"
|
#include "mongo/db/shard_role/lock_manager/exception_util.h"
|
||||||
#include "mongo/db/shard_role/lock_manager/lock_manager_defs.h"
|
#include "mongo/db/shard_role/lock_manager/lock_manager_defs.h"
|
||||||
|
|
@ -240,9 +241,8 @@ ExecutorFuture<void> RefineCollectionShardKeyCoordinator::_runImpl(
|
||||||
_performNoopWriteOnDataShardsAndConfigServer(opCtx, nss(), session, **executor);
|
_performNoopWriteOnDataShardsAndConfigServer(opCtx, nss(), session, **executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop migrations before checking indexes considering any concurrent index
|
// Stop migrations during most of the execution of the coordinator to guarantee a
|
||||||
// creation/drop with migrations could leave the cluster with inconsistent indexes,
|
// stable placement.
|
||||||
// PM-2077 should address that.
|
|
||||||
{
|
{
|
||||||
const auto session = getNewSession(opCtx);
|
const auto session = getNewSession(opCtx);
|
||||||
sharding_ddl_util::stopMigrations(
|
sharding_ddl_util::stopMigrations(
|
||||||
|
|
@ -250,7 +250,6 @@ ExecutorFuture<void> RefineCollectionShardKeyCoordinator::_runImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& ns = nss();
|
const auto& ns = nss();
|
||||||
auto const shardsWithData = getShardsWithDataForCollection(opCtx, ns);
|
|
||||||
|
|
||||||
// fetch the collection metadata and install it on each shard
|
// fetch the collection metadata and install it on each shard
|
||||||
if (feature_flags::gShardAuthoritativeCollMetadata.isEnabled(
|
if (feature_flags::gShardAuthoritativeCollMetadata.isEnabled(
|
||||||
|
|
@ -263,27 +262,45 @@ ExecutorFuture<void> RefineCollectionShardKeyCoordinator::_runImpl(
|
||||||
|
|
||||||
const auto session = getNewSession(opCtx);
|
const auto session = getNewSession(opCtx);
|
||||||
sharding_ddl_util::sendFetchCollMetadataToShards(
|
sharding_ddl_util::sendFetchCollMetadataToShards(
|
||||||
opCtx, ns, shardsWithData, session, executor, token);
|
opCtx,
|
||||||
|
ns,
|
||||||
|
getShardsWithDataForCollection(opCtx, ns),
|
||||||
|
session,
|
||||||
|
executor,
|
||||||
|
token);
|
||||||
}
|
}
|
||||||
|
|
||||||
sharding::router::CollectionRouter router(opCtx, ns);
|
ShardsvrValidateShardKeyCandidate validateRequest(ns);
|
||||||
router.route("validating indexes for refineCollectionShardKey"_sd,
|
validateRequest.setKey(_doc.getNewShardKey());
|
||||||
[&](OperationContext* opCtx, const CollectionRoutingInfo& cri) {
|
validateRequest.setEnforceUniquenessCheck(_request.getEnforceUniquenessCheck());
|
||||||
ShardsvrValidateShardKeyCandidate validateRequest(ns);
|
validateRequest.setDbName(DatabaseName::kAdmin);
|
||||||
validateRequest.setKey(_doc.getNewShardKey());
|
const auto bsonCmd = validateRequest.toBSON();
|
||||||
validateRequest.setEnforceUniquenessCheck(
|
|
||||||
_request.getEnforceUniquenessCheck());
|
|
||||||
validateRequest.setDbName(DatabaseName::kAdmin);
|
|
||||||
|
|
||||||
sharding_util::sendCommandToShardsWithVersion(
|
sharding::router::CollectionRouter router(opCtx, ns);
|
||||||
opCtx,
|
router.routeWithRoutingContext(
|
||||||
ns.dbName(),
|
"validating indexes for refineCollectionShardKey"_sd,
|
||||||
validateRequest.toBSON(),
|
[&](OperationContext* opCtx, RoutingContext& routingCtx) {
|
||||||
shardsWithData,
|
// TODO SERVER-115323: Consider using a (new) variant of
|
||||||
**executor,
|
// sendAuthenticatedCommandToShards()
|
||||||
cri,
|
const auto responses = scatterGatherVersionedTargetByRoutingTable(
|
||||||
true /* throwOnError */);
|
opCtx,
|
||||||
});
|
routingCtx,
|
||||||
|
ns,
|
||||||
|
bsonCmd,
|
||||||
|
ReadPreferenceSetting{ReadPreference::PrimaryOnly},
|
||||||
|
Shard::RetryPolicy::kIdempotent,
|
||||||
|
/*query=*/{},
|
||||||
|
/*collation=*/{},
|
||||||
|
/*letParameters=*/boost::none,
|
||||||
|
/*runtimeConstants=*/boost::none,
|
||||||
|
/*eligibleForSampling=*/false,
|
||||||
|
**executor);
|
||||||
|
|
||||||
|
for (const auto& response : responses) {
|
||||||
|
uassertStatusOK(
|
||||||
|
AsyncRequestsSender::Response::getEffectiveStatus(response));
|
||||||
|
}
|
||||||
|
});
|
||||||
}))
|
}))
|
||||||
.then(_buildPhaseHandler(
|
.then(_buildPhaseHandler(
|
||||||
Phase::kBlockCrud,
|
Phase::kBlockCrud,
|
||||||
|
|
|
||||||
|
|
@ -168,21 +168,6 @@ std::vector<AsyncRequestsSender::Response> sendCommandToShards(
|
||||||
return processShardResponses(opCtx, dbName, command, requests, executor, throwOnError);
|
return processShardResponses(opCtx, dbName, command, requests, executor, throwOnError);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AsyncRequestsSender::Response> sendCommandToShardsWithVersion(
|
|
||||||
OperationContext* opCtx,
|
|
||||||
const DatabaseName& dbName,
|
|
||||||
const BSONObj& command,
|
|
||||||
const std::vector<ShardId>& shardIds,
|
|
||||||
const std::shared_ptr<executor::TaskExecutor>& executor,
|
|
||||||
const CollectionRoutingInfo& cri,
|
|
||||||
const bool throwOnError) {
|
|
||||||
std::vector<AsyncRequestsSender::Request> requests;
|
|
||||||
for (const auto& shardId : shardIds) {
|
|
||||||
requests.emplace_back(shardId, appendShardVersion(command, cri.getShardVersion(shardId)));
|
|
||||||
}
|
|
||||||
return processShardResponses(opCtx, dbName, command, requests, executor, throwOnError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status createIndexOnCollection(OperationContext* opCtx,
|
Status createIndexOnCollection(OperationContext* opCtx,
|
||||||
const NamespaceString& ns,
|
const NamespaceString& ns,
|
||||||
const BSONObj& keys,
|
const BSONObj& keys,
|
||||||
|
|
|
||||||
|
|
@ -88,19 +88,6 @@ MONGO_MOD_NEEDS_REPLACEMENT std::vector<AsyncRequestsSender::Response> sendComma
|
||||||
const std::shared_ptr<executor::TaskExecutor>& executor,
|
const std::shared_ptr<executor::TaskExecutor>& executor,
|
||||||
bool throwOnError = true);
|
bool throwOnError = true);
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic utility to send a command to a list of shards attaching the shard version to the request.
|
|
||||||
* If `throwOnError=true`, throws in case one of the commands fails.
|
|
||||||
*/
|
|
||||||
MONGO_MOD_NEEDS_REPLACEMENT std::vector<AsyncRequestsSender::Response>
|
|
||||||
sendCommandToShardsWithVersion(OperationContext* opCtx,
|
|
||||||
const DatabaseName& dbName,
|
|
||||||
const BSONObj& command,
|
|
||||||
const std::vector<ShardId>& shardIds,
|
|
||||||
const std::shared_ptr<executor::TaskExecutor>& executor,
|
|
||||||
const CollectionRoutingInfo& cri,
|
|
||||||
bool throwOnError = true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to create an index on a collection locally.
|
* Helper function to create an index on a collection locally.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ public:
|
||||||
uassert(ErrorCodes::NamespaceNotSharded,
|
uassert(ErrorCodes::NamespaceNotSharded,
|
||||||
str::stream()
|
str::stream()
|
||||||
<< "Can't execute " << Request::kCommandName
|
<< "Can't execute " << Request::kCommandName
|
||||||
<< "on unsharded collection " << redact(ns().toStringForErrorMsg()),
|
<< " on unsharded collection " << redact(ns().toStringForErrorMsg()),
|
||||||
coll.getShardingDescription().isSharded());
|
coll.getShardingDescription().isSharded());
|
||||||
|
|
||||||
shardkeyutil::validateShardKeyIndexExistsOrCreateIfPossible(
|
shardkeyutil::validateShardKeyIndexExistsOrCreateIfPossible(
|
||||||
|
|
|
||||||
|
|
@ -362,16 +362,12 @@ std::vector<AsyncRequestsSender::Response> gatherResponsesImpl(
|
||||||
Shard::RetryPolicy retryPolicy,
|
Shard::RetryPolicy retryPolicy,
|
||||||
const std::vector<AsyncRequestsSender::Request>& requests,
|
const std::vector<AsyncRequestsSender::Request>& requests,
|
||||||
bool throwOnStaleShardVersionErrors,
|
bool throwOnStaleShardVersionErrors,
|
||||||
|
const std::shared_ptr<executor::TaskExecutor>& executor,
|
||||||
RoutingContext* routingCtx = nullptr) {
|
RoutingContext* routingCtx = nullptr) {
|
||||||
|
|
||||||
// Send the requests.
|
// Send the requests.
|
||||||
MultiStatementTransactionRequestsSender ars(
|
MultiStatementTransactionRequestsSender ars(
|
||||||
opCtx,
|
opCtx, executor, dbName, requests, readPref, retryPolicy);
|
||||||
Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(),
|
|
||||||
dbName,
|
|
||||||
requests,
|
|
||||||
readPref,
|
|
||||||
retryPolicy);
|
|
||||||
|
|
||||||
if (routingCtx && routingCtx->hasNss(nss)) {
|
if (routingCtx && routingCtx->hasNss(nss)) {
|
||||||
routingCtx->onRequestSentForNss(nss);
|
routingCtx->onRequestSentForNss(nss);
|
||||||
|
|
@ -438,15 +434,18 @@ std::vector<AsyncRequestsSender::Response> gatherResponses(
|
||||||
const ReadPreferenceSetting& readPref,
|
const ReadPreferenceSetting& readPref,
|
||||||
Shard::RetryPolicy retryPolicy,
|
Shard::RetryPolicy retryPolicy,
|
||||||
const std::vector<AsyncRequestsSender::Request>& requests,
|
const std::vector<AsyncRequestsSender::Request>& requests,
|
||||||
RoutingContext* routingCtx) {
|
RoutingContext* routingCtx,
|
||||||
return gatherResponsesImpl(opCtx,
|
std::shared_ptr<executor::TaskExecutor> executor) {
|
||||||
dbName,
|
return gatherResponsesImpl(
|
||||||
nss,
|
opCtx,
|
||||||
readPref,
|
dbName,
|
||||||
retryPolicy,
|
nss,
|
||||||
requests,
|
readPref,
|
||||||
true /* throwOnStaleShardVersionErrors */,
|
retryPolicy,
|
||||||
routingCtx);
|
requests,
|
||||||
|
true /* throwOnStaleShardVersionErrors */,
|
||||||
|
executor ? executor : Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(),
|
||||||
|
routingCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
BSONObj appendDbVersionIfPresent(BSONObj cmdObj, const CachedDatabaseInfo& dbInfo) {
|
BSONObj appendDbVersionIfPresent(BSONObj cmdObj, const CachedDatabaseInfo& dbInfo) {
|
||||||
|
|
@ -607,7 +606,8 @@ std::vector<AsyncRequestsSender::Response> scatterGatherVersionedTargetByRouting
|
||||||
const BSONObj& collation,
|
const BSONObj& collation,
|
||||||
const boost::optional<BSONObj>& letParameters,
|
const boost::optional<BSONObj>& letParameters,
|
||||||
const boost::optional<LegacyRuntimeConstants>& runtimeConstants,
|
const boost::optional<LegacyRuntimeConstants>& runtimeConstants,
|
||||||
bool eligibleForSampling) {
|
bool eligibleForSampling,
|
||||||
|
std::shared_ptr<executor::TaskExecutor> executor) {
|
||||||
auto expCtx =
|
auto expCtx =
|
||||||
makeExpressionContextWithDefaultsForTargeter(opCtx,
|
makeExpressionContextWithDefaultsForTargeter(opCtx,
|
||||||
nss,
|
nss,
|
||||||
|
|
@ -624,7 +624,8 @@ std::vector<AsyncRequestsSender::Response> scatterGatherVersionedTargetByRouting
|
||||||
retryPolicy,
|
retryPolicy,
|
||||||
query,
|
query,
|
||||||
collation,
|
collation,
|
||||||
eligibleForSampling);
|
eligibleForSampling,
|
||||||
|
std::move(executor));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::vector<AsyncRequestsSender::Response> scatterGatherVersionedTargetByRoutingTable(
|
[[nodiscard]] std::vector<AsyncRequestsSender::Response> scatterGatherVersionedTargetByRoutingTable(
|
||||||
|
|
@ -636,7 +637,8 @@ std::vector<AsyncRequestsSender::Response> scatterGatherVersionedTargetByRouting
|
||||||
Shard::RetryPolicy retryPolicy,
|
Shard::RetryPolicy retryPolicy,
|
||||||
const BSONObj& query,
|
const BSONObj& query,
|
||||||
const BSONObj& collation,
|
const BSONObj& collation,
|
||||||
bool eligibleForSampling) {
|
bool eligibleForSampling,
|
||||||
|
std::shared_ptr<executor::TaskExecutor> executor) {
|
||||||
const auto requests =
|
const auto requests =
|
||||||
buildVersionedRequestsForTargetedShards(expCtx,
|
buildVersionedRequestsForTargetedShards(expCtx,
|
||||||
nss,
|
nss,
|
||||||
|
|
@ -652,7 +654,8 @@ std::vector<AsyncRequestsSender::Response> scatterGatherVersionedTargetByRouting
|
||||||
readPref,
|
readPref,
|
||||||
retryPolicy,
|
retryPolicy,
|
||||||
requests,
|
requests,
|
||||||
&routingCtx);
|
&routingCtx,
|
||||||
|
std::move(executor));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AsyncRequestsSender::Response>
|
std::vector<AsyncRequestsSender::Response>
|
||||||
|
|
@ -686,6 +689,7 @@ scatterGatherVersionedTargetByRoutingTableNoThrowOnStaleShardVersionErrors(
|
||||||
retryPolicy,
|
retryPolicy,
|
||||||
requests,
|
requests,
|
||||||
false /* throwOnStaleShardVersionErrors */,
|
false /* throwOnStaleShardVersionErrors */,
|
||||||
|
Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(),
|
||||||
&routingCtx);
|
&routingCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -712,6 +716,7 @@ scatterGatherVersionedTargetByRoutingTableNoThrowOnStaleShardVersionErrors(
|
||||||
retryPolicy,
|
retryPolicy,
|
||||||
requests,
|
requests,
|
||||||
false /* throwOnStaleShardVersionErrors */,
|
false /* throwOnStaleShardVersionErrors */,
|
||||||
|
Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(),
|
||||||
&routingCtx);
|
&routingCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,8 @@ std::vector<AsyncRequestsSender::Response> gatherResponses(
|
||||||
const ReadPreferenceSetting& readPref,
|
const ReadPreferenceSetting& readPref,
|
||||||
Shard::RetryPolicy retryPolicy,
|
Shard::RetryPolicy retryPolicy,
|
||||||
const std::vector<AsyncRequestsSender::Request>& requests,
|
const std::vector<AsyncRequestsSender::Request>& requests,
|
||||||
RoutingContext* routingCtx = nullptr);
|
RoutingContext* routingCtx = nullptr,
|
||||||
|
std::shared_ptr<executor::TaskExecutor> executor = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of 'cmdObj' with dbVersion appended if it exists in 'dbInfo'
|
* Returns a copy of 'cmdObj' with dbVersion appended if it exists in 'dbInfo'
|
||||||
|
|
@ -332,7 +333,8 @@ std::vector<AsyncRequestsSender::Response> scatterGatherUnversionedTargetConfigS
|
||||||
const BSONObj& collation,
|
const BSONObj& collation,
|
||||||
const boost::optional<BSONObj>& letParameters,
|
const boost::optional<BSONObj>& letParameters,
|
||||||
const boost::optional<LegacyRuntimeConstants>& runtimeConstants,
|
const boost::optional<LegacyRuntimeConstants>& runtimeConstants,
|
||||||
bool eligibleForSampling = false);
|
bool eligibleForSampling = false,
|
||||||
|
std::shared_ptr<executor::TaskExecutor> executor = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This overload is for callers which already have a fully initialized 'ExpressionContext' (e.g.
|
* This overload is for callers which already have a fully initialized 'ExpressionContext' (e.g.
|
||||||
|
|
@ -347,7 +349,8 @@ std::vector<AsyncRequestsSender::Response> scatterGatherUnversionedTargetConfigS
|
||||||
Shard::RetryPolicy retryPolicy,
|
Shard::RetryPolicy retryPolicy,
|
||||||
const BSONObj& query,
|
const BSONObj& query,
|
||||||
const BSONObj& collation,
|
const BSONObj& collation,
|
||||||
bool eligibleForSampling = false);
|
bool eligibleForSampling = false,
|
||||||
|
std::shared_ptr<executor::TaskExecutor> executor = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for dispatching versioned commands on a namespace, deciding which shards to
|
* Utility for dispatching versioned commands on a namespace, deciding which shards to
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue