mirror of https://github.com/mongodb/mongo
SERVER-114264 Port adhoc command shardVersion construction to cluster_commands_helpers.h (#44621)
GitOrigin-RevId: 5e66ea0cd87e740e27a9759b6e033239a6f584fa
This commit is contained in:
parent
7380779c9e
commit
aaada80f38
|
|
@ -29,31 +29,22 @@
|
||||||
|
|
||||||
#include "mongo/base/error_codes.h"
|
#include "mongo/base/error_codes.h"
|
||||||
#include "mongo/base/status_with.h"
|
#include "mongo/base/status_with.h"
|
||||||
#include "mongo/bson/bsonobj.h"
|
|
||||||
#include "mongo/client/read_preference.h"
|
#include "mongo/client/read_preference.h"
|
||||||
#include "mongo/db/auth/action_type.h"
|
#include "mongo/db/auth/action_type.h"
|
||||||
#include "mongo/db/auth/authorization_session.h"
|
#include "mongo/db/auth/authorization_session.h"
|
||||||
#include "mongo/db/auth/resource_pattern.h"
|
#include "mongo/db/auth/resource_pattern.h"
|
||||||
#include "mongo/db/commands.h"
|
#include "mongo/db/commands.h"
|
||||||
#include "mongo/db/database_name.h"
|
#include "mongo/db/database_name.h"
|
||||||
#include "mongo/db/global_catalog/chunk_manager.h"
|
|
||||||
#include "mongo/db/namespace_string.h"
|
#include "mongo/db/namespace_string.h"
|
||||||
#include "mongo/db/operation_context.h"
|
#include "mongo/db/operation_context.h"
|
||||||
#include "mongo/db/router_role/cluster_commands_helpers.h"
|
#include "mongo/db/router_role/cluster_commands_helpers.h"
|
||||||
#include "mongo/db/router_role/routing_cache/catalog_cache.h"
|
#include "mongo/db/router_role/routing_cache/catalog_cache.h"
|
||||||
#include "mongo/db/service_context.h"
|
#include "mongo/db/service_context.h"
|
||||||
#include "mongo/db/sharding_environment/client/shard.h"
|
#include "mongo/db/sharding_environment/client/shard.h"
|
||||||
#include "mongo/db/sharding_environment/grid.h"
|
|
||||||
#include "mongo/db/sharding_environment/shard_id.h"
|
|
||||||
#include "mongo/db/topology/shard_registry.h"
|
|
||||||
#include "mongo/db/versioning_protocol/shard_version.h"
|
|
||||||
#include "mongo/idl/idl_parser.h"
|
#include "mongo/idl/idl_parser.h"
|
||||||
#include "mongo/rpc/op_msg.h"
|
|
||||||
#include "mongo/s/analyze_shard_key_common_gen.h"
|
|
||||||
#include "mongo/s/configure_query_analyzer_cmd_gen.h"
|
#include "mongo/s/configure_query_analyzer_cmd_gen.h"
|
||||||
#include "mongo/util/assert_util.h"
|
#include "mongo/util/assert_util.h"
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand
|
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand
|
||||||
|
|
@ -63,14 +54,6 @@ namespace analyze_shard_key {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new command object with database version appended to it based on the given routing
|
|
||||||
* info.
|
|
||||||
*/
|
|
||||||
BSONObj makeVersionedCmdObj(const CollectionRoutingInfo& cri, const BSONObj& unversionedCmdObj) {
|
|
||||||
return appendDbVersionIfPresent(unversionedCmdObj, cri.getDbVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigureQueryAnalyzerCmd : public TypedCommand<ConfigureQueryAnalyzerCmd> {
|
class ConfigureQueryAnalyzerCmd : public TypedCommand<ConfigureQueryAnalyzerCmd> {
|
||||||
public:
|
public:
|
||||||
using Request = ConfigureQueryAnalyzer;
|
using Request = ConfigureQueryAnalyzer;
|
||||||
|
|
|
||||||
|
|
@ -462,15 +462,11 @@ public:
|
||||||
? cm.getTimeseriesFields()
|
? cm.getTimeseriesFields()
|
||||||
: boost::none;
|
: boost::none;
|
||||||
|
|
||||||
auto cmdObj =
|
const auto cmdObj =
|
||||||
createAggregateCmdObj(opCtx, parsedInfoFromRequest, nss, timeseriesFields);
|
createAggregateCmdObj(opCtx, parsedInfoFromRequest, nss, timeseriesFields);
|
||||||
|
|
||||||
std::vector<AsyncRequestsSender::Request> requests;
|
const auto requests = buildVersionedRequests(
|
||||||
requests.reserve(allShardsContainingChunksForNs.size());
|
opCtx, nss, cri, allShardsContainingChunksForNs, cmdObj);
|
||||||
for (const auto& shardId : allShardsContainingChunksForNs) {
|
|
||||||
requests.emplace_back(
|
|
||||||
shardId, appendShardVersion(cmdObj, cri.getShardVersion(shardId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiStatementTransactionRequestsSender ars(
|
MultiStatementTransactionRequestsSender ars(
|
||||||
opCtx,
|
opCtx,
|
||||||
|
|
@ -607,20 +603,14 @@ public:
|
||||||
[&](OperationContext* opCtx, RoutingContext& routingCtx) {
|
[&](OperationContext* opCtx, RoutingContext& routingCtx) {
|
||||||
const auto& cri = routingCtx.getCollectionRoutingInfo(nss);
|
const auto& cri = routingCtx.getCollectionRoutingInfo(nss);
|
||||||
|
|
||||||
auto allShardsContainingChunksForNs =
|
const auto cmdObj =
|
||||||
getShardsToTarget(opCtx, cri, nss, parsedInfoFromRequest);
|
|
||||||
auto cmdObj =
|
|
||||||
createAggregateCmdObj(opCtx, parsedInfoFromRequest, nss, boost::none);
|
createAggregateCmdObj(opCtx, parsedInfoFromRequest, nss, boost::none);
|
||||||
|
const auto requests = buildVersionedRequests(
|
||||||
const auto aggExplainCmdObj = ClusterExplain::wrapAsExplain(cmdObj, verbosity);
|
opCtx,
|
||||||
|
nss,
|
||||||
std::vector<AsyncRequestsSender::Request> requests;
|
cri,
|
||||||
requests.reserve(allShardsContainingChunksForNs.size());
|
getShardsToTarget(opCtx, cri, nss, parsedInfoFromRequest),
|
||||||
for (const auto& shardId : allShardsContainingChunksForNs) {
|
ClusterExplain::wrapAsExplain(cmdObj, verbosity));
|
||||||
requests.emplace_back(
|
|
||||||
shardId,
|
|
||||||
appendShardVersion(aggExplainCmdObj, cri.getShardVersion(shardId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer timer;
|
Timer timer;
|
||||||
MultiStatementTransactionRequestsSender ars(
|
MultiStatementTransactionRequestsSender ars(
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
#include "mongo/base/error_extra_info.h"
|
#include "mongo/base/error_extra_info.h"
|
||||||
#include "mongo/base/status_with.h"
|
#include "mongo/base/status_with.h"
|
||||||
#include "mongo/bson/bsonelement.h"
|
#include "mongo/bson/bsonelement.h"
|
||||||
#include "mongo/bson/bsonmisc.h"
|
|
||||||
#include "mongo/bson/bsontypes.h"
|
#include "mongo/bson/bsontypes.h"
|
||||||
#include "mongo/bson/util/bson_extract.h"
|
#include "mongo/bson/util/bson_extract.h"
|
||||||
#include "mongo/client/connection_string.h"
|
#include "mongo/client/connection_string.h"
|
||||||
|
|
@ -50,7 +49,6 @@
|
||||||
#include "mongo/db/generic_argument_util.h"
|
#include "mongo/db/generic_argument_util.h"
|
||||||
#include "mongo/db/global_catalog/chunk.h"
|
#include "mongo/db/global_catalog/chunk.h"
|
||||||
#include "mongo/db/global_catalog/chunk_manager.h"
|
#include "mongo/db/global_catalog/chunk_manager.h"
|
||||||
#include "mongo/db/global_catalog/ddl/cluster_ddl.h"
|
|
||||||
#include "mongo/db/global_catalog/type_collection_common_types_gen.h"
|
#include "mongo/db/global_catalog/type_collection_common_types_gen.h"
|
||||||
#include "mongo/db/internal_transactions_feature_flag_gen.h"
|
#include "mongo/db/internal_transactions_feature_flag_gen.h"
|
||||||
#include "mongo/db/pipeline/expression_context.h"
|
#include "mongo/db/pipeline/expression_context.h"
|
||||||
|
|
@ -60,8 +58,6 @@
|
||||||
#include "mongo/db/query/write_ops/write_ops_gen.h"
|
#include "mongo/db/query/write_ops/write_ops_gen.h"
|
||||||
#include "mongo/db/repl/read_concern_args.h"
|
#include "mongo/db/repl/read_concern_args.h"
|
||||||
#include "mongo/db/router_role/cluster_commands_helpers.h"
|
#include "mongo/db/router_role/cluster_commands_helpers.h"
|
||||||
#include "mongo/db/router_role/collection_routing_info_targeter.h"
|
|
||||||
#include "mongo/db/router_role/routing_cache/catalog_cache.h"
|
|
||||||
#include "mongo/db/server_options.h"
|
#include "mongo/db/server_options.h"
|
||||||
#include "mongo/db/shard_role/shard_catalog/document_validation.h"
|
#include "mongo/db/shard_role/shard_catalog/document_validation.h"
|
||||||
#include "mongo/db/shard_role/shard_catalog/raw_data_operation.h"
|
#include "mongo/db/shard_role/shard_catalog/raw_data_operation.h"
|
||||||
|
|
@ -70,9 +66,7 @@
|
||||||
#include "mongo/db/stats/counters.h"
|
#include "mongo/db/stats/counters.h"
|
||||||
#include "mongo/db/storage/duplicate_key_error_info.h"
|
#include "mongo/db/storage/duplicate_key_error_info.h"
|
||||||
#include "mongo/db/storage/storage_parameters_gen.h"
|
#include "mongo/db/storage/storage_parameters_gen.h"
|
||||||
#include "mongo/db/timeseries/timeseries_request_util.h"
|
|
||||||
#include "mongo/db/timeseries/timeseries_update_delete_util.h"
|
#include "mongo/db/timeseries/timeseries_update_delete_util.h"
|
||||||
#include "mongo/db/timeseries/timeseries_write_util.h"
|
|
||||||
#include "mongo/db/transaction/transaction_api.h"
|
#include "mongo/db/transaction/transaction_api.h"
|
||||||
#include "mongo/db/version_context.h"
|
#include "mongo/db/version_context.h"
|
||||||
#include "mongo/db/write_concern_options.h"
|
#include "mongo/db/write_concern_options.h"
|
||||||
|
|
@ -84,7 +78,6 @@
|
||||||
#include "mongo/s/async_requests_sender.h"
|
#include "mongo/s/async_requests_sender.h"
|
||||||
#include "mongo/s/commands/document_shard_key_update_util.h"
|
#include "mongo/s/commands/document_shard_key_update_util.h"
|
||||||
#include "mongo/s/commands/query_cmd/cluster_explain.h"
|
#include "mongo/s/commands/query_cmd/cluster_explain.h"
|
||||||
#include "mongo/s/multi_statement_transaction_requests_sender.h"
|
|
||||||
#include "mongo/s/query/shard_key_pattern_query_util.h"
|
#include "mongo/s/query/shard_key_pattern_query_util.h"
|
||||||
#include "mongo/s/query_analysis_sampler_util.h"
|
#include "mongo/s/query_analysis_sampler_util.h"
|
||||||
#include "mongo/s/request_types/cluster_commands_without_shard_key_gen.h"
|
#include "mongo/s/request_types/cluster_commands_without_shard_key_gen.h"
|
||||||
|
|
@ -407,27 +400,17 @@ BSONObj prepareCmdObjForPassthrough(
|
||||||
OperationContext* opCtx,
|
OperationContext* opCtx,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
bool isExplain,
|
bool eligibleForSampling,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
|
||||||
boost::optional<bool> allowShardKeyUpdatesWithoutFullShardKeyInQuery) {
|
boost::optional<bool> allowShardKeyUpdatesWithoutFullShardKeyInQuery) {
|
||||||
BSONObj filteredCmdObj = CommandHelpers::filterCommandRequestForPassthrough(cmdObj);
|
BSONObj newCmdObj = CommandHelpers::filterCommandRequestForPassthrough(cmdObj);
|
||||||
if (!isExplain) {
|
if (eligibleForSampling) {
|
||||||
if (auto sampleId = analyze_shard_key::tryGenerateSampleId(
|
if (auto sampleId = analyze_shard_key::tryGenerateSampleId(
|
||||||
opCtx, nss, cmdObj.firstElementFieldNameStringData())) {
|
opCtx, nss, cmdObj.firstElementFieldNameStringData())) {
|
||||||
filteredCmdObj =
|
newCmdObj =
|
||||||
analyze_shard_key::appendSampleId(std::move(filteredCmdObj), std::move(*sampleId));
|
analyze_shard_key::appendSampleId(std::move(newCmdObj), std::move(*sampleId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BSONObj newCmdObj(std::move(filteredCmdObj));
|
|
||||||
if (dbVersion) {
|
|
||||||
newCmdObj = appendDbVersionIfPresent(newCmdObj, *dbVersion);
|
|
||||||
}
|
|
||||||
if (shardVersion) {
|
|
||||||
newCmdObj = appendShardVersion(newCmdObj, *shardVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opCtx->isRetryableWrite()) {
|
if (opCtx->isRetryableWrite()) {
|
||||||
if (!newCmdObj.hasField(write_ops::WriteCommandRequestBase::kStmtIdFieldName)) {
|
if (!newCmdObj.hasField(write_ops::WriteCommandRequestBase::kStmtIdFieldName)) {
|
||||||
BSONObjBuilder bob(newCmdObj);
|
BSONObjBuilder bob(newCmdObj);
|
||||||
|
|
@ -783,23 +766,16 @@ Status FindAndModifyCmd::explain(OperationContext* opCtx,
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto shardVersion = cri.hasRoutingTable()
|
|
||||||
? boost::make_optional(cri.getShardVersion(*shardId))
|
|
||||||
: boost::make_optional(!cri.getDbVersion().isFixed(), ShardVersion::UNTRACKED());
|
|
||||||
auto dbVersion =
|
|
||||||
cri.hasRoutingTable() ? boost::none : boost::make_optional(cri.getDbVersion());
|
|
||||||
|
|
||||||
_runCommand(opCtx,
|
_runCommand(opCtx,
|
||||||
*shardId,
|
*shardId,
|
||||||
shardVersion,
|
cri,
|
||||||
dbVersion,
|
|
||||||
nss,
|
nss,
|
||||||
applyReadWriteConcern(
|
applyReadWriteConcern(
|
||||||
opCtx, false, false, makeExplainCmd(opCtx, cmdObj, verbosity)),
|
opCtx, false, false, makeExplainCmd(opCtx, cmdObj, verbosity)),
|
||||||
true /* isExplain */,
|
|
||||||
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
||||||
isTimeseriesLogicalRequest,
|
isTimeseriesLogicalRequest,
|
||||||
&bob);
|
&bob,
|
||||||
|
false /*explain is not eligible for sampling*/);
|
||||||
|
|
||||||
const auto millisElapsed = timer.millis();
|
const auto millisElapsed = timer.millis();
|
||||||
|
|
||||||
|
|
@ -961,16 +937,15 @@ bool FindAndModifyCmd::run(OperationContext* opCtx,
|
||||||
// protocol.
|
// protocol.
|
||||||
_runCommand(opCtx,
|
_runCommand(opCtx,
|
||||||
*shardId,
|
*shardId,
|
||||||
cri.getShardVersion(*shardId),
|
cri,
|
||||||
boost::none,
|
|
||||||
nss,
|
nss,
|
||||||
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
||||||
false /* isExplain */,
|
|
||||||
allowShardKeyUpdatesWithoutFullShardKeyInQuery,
|
allowShardKeyUpdatesWithoutFullShardKeyInQuery,
|
||||||
isTimeseriesLogicalRequest,
|
isTimeseriesLogicalRequest,
|
||||||
&result);
|
&result);
|
||||||
} else {
|
} else {
|
||||||
_runCommandWithoutShardKey(opCtx,
|
_runCommandWithoutShardKey(opCtx,
|
||||||
|
cri,
|
||||||
nss,
|
nss,
|
||||||
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
||||||
isTimeseriesLogicalRequest,
|
isTimeseriesLogicalRequest,
|
||||||
|
|
@ -988,11 +963,9 @@ bool FindAndModifyCmd::run(OperationContext* opCtx,
|
||||||
|
|
||||||
_runCommand(opCtx,
|
_runCommand(opCtx,
|
||||||
shardId,
|
shardId,
|
||||||
cri.getShardVersion(shardId),
|
cri,
|
||||||
boost::none,
|
|
||||||
nss,
|
nss,
|
||||||
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
||||||
false /* isExplain */,
|
|
||||||
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
||||||
isTimeseriesLogicalRequest,
|
isTimeseriesLogicalRequest,
|
||||||
&result);
|
&result);
|
||||||
|
|
@ -1000,17 +973,14 @@ bool FindAndModifyCmd::run(OperationContext* opCtx,
|
||||||
} else {
|
} else {
|
||||||
getQueryCounters(opCtx).findAndModifyUnshardedCount.increment(1);
|
getQueryCounters(opCtx).findAndModifyUnshardedCount.increment(1);
|
||||||
|
|
||||||
_runCommand(
|
_runCommand(opCtx,
|
||||||
opCtx,
|
cri.getDbPrimaryShardId(),
|
||||||
cri.getDbPrimaryShardId(),
|
cri,
|
||||||
boost::make_optional(!cri.getDbVersion().isFixed(), ShardVersion::UNTRACKED()),
|
nss,
|
||||||
cri.getDbVersion(),
|
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
||||||
nss,
|
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
||||||
applyReadWriteConcern(opCtx, this, cmdObjForShard),
|
isTimeseriesLogicalRequest,
|
||||||
false /* isExplain */,
|
&result);
|
||||||
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
|
||||||
isTimeseriesLogicalRequest,
|
|
||||||
&result);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1038,16 +1008,15 @@ bool FindAndModifyCmd::getCrudProcessedFromCmd(const BSONObj& cmdObj) {
|
||||||
|
|
||||||
// Catches errors in the given response, and reruns the command if necessary. Uses the given
|
// Catches errors in the given response, and reruns the command if necessary. Uses the given
|
||||||
// response to construct the findAndModify command result passed to the client.
|
// response to construct the findAndModify command result passed to the client.
|
||||||
void FindAndModifyCmd::_constructResult(OperationContext* opCtx,
|
void FindAndModifyCmd::_handleResponseAndConstructResult(OperationContext* opCtx,
|
||||||
const ShardId& shardId,
|
const ShardId& shardId,
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
const CollectionRoutingInfo& cri,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
const NamespaceString& nss,
|
||||||
const NamespaceString& nss,
|
const BSONObj& cmdObj,
|
||||||
const BSONObj& cmdObj,
|
const Status& responseStatus,
|
||||||
const Status& responseStatus,
|
const BSONObj& response,
|
||||||
const BSONObj& response,
|
bool isTimeseriesViewRequest,
|
||||||
bool isTimeseriesViewRequest,
|
BSONObjBuilder* result) {
|
||||||
BSONObjBuilder* result) {
|
|
||||||
auto txnRouter = TransactionRouter::get(opCtx);
|
auto txnRouter = TransactionRouter::get(opCtx);
|
||||||
bool isRetryableWrite = opCtx->getTxnNumber() && !txnRouter;
|
bool isRetryableWrite = opCtx->getTxnNumber() && !txnRouter;
|
||||||
|
|
||||||
|
|
@ -1068,14 +1037,8 @@ void FindAndModifyCmd::_constructResult(OperationContext* opCtx,
|
||||||
opCtx->setQuerySamplingOptions(QuerySamplingOptions::kOptOut);
|
opCtx->setQuerySamplingOptions(QuerySamplingOptions::kOptOut);
|
||||||
|
|
||||||
if (isRetryableWrite) {
|
if (isRetryableWrite) {
|
||||||
_handleWouldChangeOwningShardErrorRetryableWriteLegacy(opCtx,
|
_handleWouldChangeOwningShardErrorRetryableWriteLegacy(
|
||||||
shardId,
|
opCtx, shardId, cri, nss, cmdObj, isTimeseriesViewRequest, result);
|
||||||
shardVersion,
|
|
||||||
dbVersion,
|
|
||||||
nss,
|
|
||||||
cmdObj,
|
|
||||||
isTimeseriesViewRequest,
|
|
||||||
result);
|
|
||||||
} else {
|
} else {
|
||||||
handleWouldChangeOwningShardErrorTransactionLegacy(opCtx,
|
handleWouldChangeOwningShardErrorTransactionLegacy(opCtx,
|
||||||
nss,
|
nss,
|
||||||
|
|
@ -1104,6 +1067,7 @@ void FindAndModifyCmd::_constructResult(OperationContext* opCtx,
|
||||||
|
|
||||||
// Two-phase protocol to run a findAndModify command without a shard key or _id.
|
// Two-phase protocol to run a findAndModify command without a shard key or _id.
|
||||||
void FindAndModifyCmd::_runCommandWithoutShardKey(OperationContext* opCtx,
|
void FindAndModifyCmd::_runCommandWithoutShardKey(OperationContext* opCtx,
|
||||||
|
const CollectionRoutingInfo& cri,
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
bool isTimeseriesViewRequest,
|
bool isTimeseriesViewRequest,
|
||||||
|
|
@ -1115,9 +1079,7 @@ void FindAndModifyCmd::_runCommandWithoutShardKey(OperationContext* opCtx,
|
||||||
prepareCmdObjForPassthrough(opCtx,
|
prepareCmdObjForPassthrough(opCtx,
|
||||||
cmdObj,
|
cmdObj,
|
||||||
nss,
|
nss,
|
||||||
false /* isExplain */,
|
true /* eligibleForSampling */,
|
||||||
boost::none /* dbVersion */,
|
|
||||||
boost::none /* shardVersion */,
|
|
||||||
allowShardKeyUpdatesWithoutFullShardKeyInQuery);
|
allowShardKeyUpdatesWithoutFullShardKeyInQuery);
|
||||||
|
|
||||||
// TODO SERVER-108928 - Handle this inside of prepareCmdObjForPassthrough.
|
// TODO SERVER-108928 - Handle this inside of prepareCmdObjForPassthrough.
|
||||||
|
|
@ -1166,16 +1128,15 @@ void FindAndModifyCmd::_runCommandWithoutShardKey(OperationContext* opCtx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract findAndModify command result from the result of the two phase write protocol.
|
// Extract findAndModify command result from the result of the two phase write protocol.
|
||||||
_constructResult(opCtx,
|
_handleResponseAndConstructResult(opCtx,
|
||||||
shardId,
|
shardId,
|
||||||
boost::none /* shardVersion */,
|
cri,
|
||||||
boost::none /* dbVersion */,
|
nss,
|
||||||
nss,
|
cmdObj,
|
||||||
cmdObj,
|
swRes.getStatus(),
|
||||||
swRes.getStatus(),
|
cmdResponse,
|
||||||
cmdResponse,
|
isTimeseriesViewRequest,
|
||||||
isTimeseriesViewRequest,
|
result);
|
||||||
result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two-phase protocol to run an explain for a findAndModify command without a shard key or _id.
|
// Two-phase protocol to run an explain for a findAndModify command without a shard key or _id.
|
||||||
|
|
@ -1188,9 +1149,7 @@ void FindAndModifyCmd::_runExplainWithoutShardKey(OperationContext* opCtx,
|
||||||
opCtx,
|
opCtx,
|
||||||
originalExplainObj,
|
originalExplainObj,
|
||||||
nss,
|
nss,
|
||||||
true /* isExplain */,
|
false /* eligibleForSampling */,
|
||||||
boost::none /* dbVersion */,
|
|
||||||
boost::none /* shardVersion */,
|
|
||||||
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */);
|
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */);
|
||||||
|
|
||||||
auto explainObj = translateExplainObjForRawData(opCtx, cmdObjForPassthrough, nss);
|
auto explainObj = translateExplainObjForRawData(opCtx, cmdObjForPassthrough, nss);
|
||||||
|
|
@ -1236,62 +1195,62 @@ void FindAndModifyCmd::_runExplainWithoutShardKey(OperationContext* opCtx,
|
||||||
void FindAndModifyCmd::_runCommand(
|
void FindAndModifyCmd::_runCommand(
|
||||||
OperationContext* opCtx,
|
OperationContext* opCtx,
|
||||||
const ShardId& shardId,
|
const ShardId& shardId,
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
const CollectionRoutingInfo& cri,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
bool isExplain,
|
|
||||||
boost::optional<bool> allowShardKeyUpdatesWithoutFullShardKeyInQuery,
|
boost::optional<bool> allowShardKeyUpdatesWithoutFullShardKeyInQuery,
|
||||||
bool isTimeseriesViewRequest,
|
bool isTimeseriesViewRequest,
|
||||||
BSONObjBuilder* result) {
|
BSONObjBuilder* result,
|
||||||
|
bool eligibleForSampling) {
|
||||||
|
|
||||||
auto txnRouter = TransactionRouter::get(opCtx);
|
auto txnRouter = TransactionRouter::get(opCtx);
|
||||||
bool isRetryableWrite = opCtx->getTxnNumber() && !txnRouter;
|
bool isRetryableWrite = opCtx->getTxnNumber() && !txnRouter;
|
||||||
|
|
||||||
const auto response = [&] {
|
// Pass 'false' to `eligibleForSampling` since scatterGatherVersionedTargetToShards is going to
|
||||||
std::vector<AsyncRequestsSender::Request> requests;
|
// add those fields.
|
||||||
auto cmdObjForPassthrough =
|
const auto passthroughCmdObj =
|
||||||
prepareCmdObjForPassthrough(opCtx,
|
prepareCmdObjForPassthrough(opCtx,
|
||||||
cmdObj,
|
cmdObj,
|
||||||
nss,
|
nss,
|
||||||
isExplain,
|
/*eligibleForSampling=*/false,
|
||||||
dbVersion,
|
allowShardKeyUpdatesWithoutFullShardKeyInQuery);
|
||||||
shardVersion,
|
// Create a RoutingContext from the CollectionRoutingInfo.
|
||||||
allowShardKeyUpdatesWithoutFullShardKeyInQuery);
|
auto routingCtx = RoutingContext::createSynthetic({{nss, cri}});
|
||||||
requests.emplace_back(shardId, cmdObjForPassthrough);
|
const auto responses = scatterGatherVersionedTargetToShards(
|
||||||
|
opCtx,
|
||||||
|
*routingCtx,
|
||||||
|
nss.dbName(),
|
||||||
|
nss,
|
||||||
|
{shardId},
|
||||||
|
passthroughCmdObj,
|
||||||
|
kPrimaryOnlyReadPreference,
|
||||||
|
isRetryableWrite ? Shard::RetryPolicy::kIdempotent
|
||||||
|
: Shard::RetryPolicy::kStrictlyNotIdempotent,
|
||||||
|
eligibleForSampling);
|
||||||
|
|
||||||
MultiStatementTransactionRequestsSender ars(
|
tassert(11426400,
|
||||||
opCtx,
|
fmt::format("scatterGatherVersionedTargetToShards returned more than one response "
|
||||||
Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(),
|
"despite passing a single shardId: size: {}",
|
||||||
nss.dbName(),
|
responses.size()),
|
||||||
requests,
|
responses.size() == 1);
|
||||||
kPrimaryOnlyReadPreference,
|
|
||||||
isRetryableWrite ? Shard::RetryPolicy::kIdempotent
|
|
||||||
: Shard::RetryPolicy::kStrictlyNotIdempotent);
|
|
||||||
|
|
||||||
auto response = ars.next();
|
const auto& response = uassertStatusOK(responses.front().swResponse);
|
||||||
invariant(ars.done());
|
_handleResponseAndConstructResult(opCtx,
|
||||||
|
shardId,
|
||||||
return uassertStatusOK(std::move(response.swResponse));
|
cri,
|
||||||
}();
|
nss,
|
||||||
|
cmdObj,
|
||||||
_constructResult(opCtx,
|
getStatusFromCommandResult(response.data),
|
||||||
shardId,
|
response.data,
|
||||||
shardVersion,
|
isTimeseriesViewRequest,
|
||||||
dbVersion,
|
result);
|
||||||
nss,
|
|
||||||
cmdObj,
|
|
||||||
getStatusFromCommandResult(response.data),
|
|
||||||
response.data,
|
|
||||||
isTimeseriesViewRequest,
|
|
||||||
result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO SERVER-67429: Remove this function.
|
// TODO SERVER-67429: Remove this function.
|
||||||
void FindAndModifyCmd::_handleWouldChangeOwningShardErrorRetryableWriteLegacy(
|
void FindAndModifyCmd::_handleWouldChangeOwningShardErrorRetryableWriteLegacy(
|
||||||
OperationContext* opCtx,
|
OperationContext* opCtx,
|
||||||
const ShardId& shardId,
|
const ShardId& shardId,
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
const CollectionRoutingInfo& cri,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
bool isTimeseriesViewRequest,
|
bool isTimeseriesViewRequest,
|
||||||
|
|
@ -1321,17 +1280,15 @@ void FindAndModifyCmd::_handleWouldChangeOwningShardErrorRetryableWriteLegacy(
|
||||||
isTimeseriesViewRequest)) {
|
isTimeseriesViewRequest)) {
|
||||||
getQueryCounters(opCtx).findAndModifyNonTargetedShardedCount.increment(1);
|
getQueryCounters(opCtx).findAndModifyNonTargetedShardedCount.increment(1);
|
||||||
_runCommandWithoutShardKey(
|
_runCommandWithoutShardKey(
|
||||||
opCtx, nss, stripWriteConcern(cmdObj), isTimeseriesViewRequest, result);
|
opCtx, cri, nss, stripWriteConcern(cmdObj), isTimeseriesViewRequest, result);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
getQueryCounters(opCtx).findAndModifyTargetedShardedCount.increment(1);
|
getQueryCounters(opCtx).findAndModifyTargetedShardedCount.increment(1);
|
||||||
_runCommand(opCtx,
|
_runCommand(opCtx,
|
||||||
shardId,
|
shardId,
|
||||||
shardVersion,
|
cri,
|
||||||
dbVersion,
|
|
||||||
nss,
|
nss,
|
||||||
stripWriteConcern(cmdObj),
|
stripWriteConcern(cmdObj),
|
||||||
false /* isExplain */,
|
|
||||||
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
boost::none /* allowShardKeyUpdatesWithoutFullShardKeyInQuery */,
|
||||||
isTimeseriesViewRequest,
|
isTimeseriesViewRequest,
|
||||||
result);
|
result);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "mongo/db/query/explain_options.h"
|
#include "mongo/db/query/explain_options.h"
|
||||||
#include "mongo/db/read_concern_support_result.h"
|
#include "mongo/db/read_concern_support_result.h"
|
||||||
#include "mongo/db/repl/read_concern_level.h"
|
#include "mongo/db/repl/read_concern_level.h"
|
||||||
|
#include "mongo/db/router_role/routing_cache/catalog_cache.h"
|
||||||
#include "mongo/db/service_context.h"
|
#include "mongo/db/service_context.h"
|
||||||
#include "mongo/db/sharding_environment/shard_id.h"
|
#include "mongo/db/sharding_environment/shard_id.h"
|
||||||
#include "mongo/db/versioning_protocol/database_version.h"
|
#include "mongo/db/versioning_protocol/database_version.h"
|
||||||
|
|
@ -154,19 +155,19 @@ private:
|
||||||
|
|
||||||
// Catches errors in the given response, and reruns the command if necessary. Uses the given
|
// Catches errors in the given response, and reruns the command if necessary. Uses the given
|
||||||
// response to construct the findAndModify command result passed to the client.
|
// response to construct the findAndModify command result passed to the client.
|
||||||
static void _constructResult(OperationContext* opCtx,
|
static void _handleResponseAndConstructResult(OperationContext* opCtx,
|
||||||
const ShardId& shardId,
|
const ShardId& shardId,
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
const CollectionRoutingInfo& cri,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
const NamespaceString& nss,
|
||||||
const NamespaceString& nss,
|
const BSONObj& cmdObj,
|
||||||
const BSONObj& cmdObj,
|
const Status& responseStatus,
|
||||||
const Status& responseStatus,
|
const BSONObj& response,
|
||||||
const BSONObj& response,
|
bool isTimeseriesViewRequest,
|
||||||
bool isTimeseriesViewRequest,
|
BSONObjBuilder* result);
|
||||||
BSONObjBuilder* result);
|
|
||||||
|
|
||||||
// Two-phase protocol to run a findAndModify command without a shard key or _id.
|
// Two-phase protocol to run a findAndModify command without a shard key or _id.
|
||||||
static void _runCommandWithoutShardKey(OperationContext* opCtx,
|
static void _runCommandWithoutShardKey(OperationContext* opCtx,
|
||||||
|
const CollectionRoutingInfo& cri,
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
bool isTimeseriesViewRequest,
|
bool isTimeseriesViewRequest,
|
||||||
|
|
@ -182,21 +183,19 @@ private:
|
||||||
// Command invocation to be used if a shard key is specified or the collection is unsharded.
|
// Command invocation to be used if a shard key is specified or the collection is unsharded.
|
||||||
static void _runCommand(OperationContext* opCtx,
|
static void _runCommand(OperationContext* opCtx,
|
||||||
const ShardId& shardId,
|
const ShardId& shardId,
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
const CollectionRoutingInfo& cri,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
bool isExplain,
|
|
||||||
boost::optional<bool> allowShardKeyUpdatesWithoutFullShardKeyInQuery,
|
boost::optional<bool> allowShardKeyUpdatesWithoutFullShardKeyInQuery,
|
||||||
bool isTimeseriesViewRequest,
|
bool isTimeseriesViewRequest,
|
||||||
BSONObjBuilder* result);
|
BSONObjBuilder* result,
|
||||||
|
bool eligibleForSampling = true);
|
||||||
|
|
||||||
// TODO SERVER-67429: Remove this function.
|
// TODO SERVER-67429: Remove this function.
|
||||||
static void _handleWouldChangeOwningShardErrorRetryableWriteLegacy(
|
static void _handleWouldChangeOwningShardErrorRetryableWriteLegacy(
|
||||||
OperationContext* opCtx,
|
OperationContext* opCtx,
|
||||||
const ShardId& shardId,
|
const ShardId& shardId,
|
||||||
const boost::optional<ShardVersion>& shardVersion,
|
const CollectionRoutingInfo& cri,
|
||||||
const boost::optional<DatabaseVersion>& dbVersion,
|
|
||||||
const NamespaceString& nss,
|
const NamespaceString& nss,
|
||||||
const BSONObj& cmdObj,
|
const BSONObj& cmdObj,
|
||||||
bool isTimeseriesViewRequest,
|
bool isTimeseriesViewRequest,
|
||||||
|
|
|
||||||
|
|
@ -155,48 +155,48 @@ static const BSONObj kGeoNearDistanceMetaProjection = BSON("$meta" << "geoNearDi
|
||||||
|
|
||||||
const char kFindCmdName[] = "find";
|
const char kFindCmdName[] = "find";
|
||||||
|
|
||||||
std::unique_ptr<FindCommandRequest> makeFindCommandForShards(OperationContext* opCtx,
|
BSONObj makeFindCommandForShards(OperationContext* opCtx,
|
||||||
const std::set<ShardId>& shardIds,
|
const std::set<ShardId>& shardIds,
|
||||||
const CanonicalQuery& query,
|
const CanonicalQuery& query,
|
||||||
const boost::optional<UUID> sampleId,
|
bool requestQueryStatsFromRemotes,
|
||||||
bool requestQueryStatsFromRemotes,
|
const UUID& opKey) {
|
||||||
const UUID& opKey) {
|
auto findCommand = [&]() -> FindCommandRequest {
|
||||||
std::unique_ptr<FindCommandRequest> findCommand;
|
if (shardIds.size() > 1) {
|
||||||
if (shardIds.size() > 1) {
|
return *uassertStatusOK(ClusterFind::transformQueryForShards(query));
|
||||||
findCommand = uassertStatusOK(ClusterFind::transformQueryForShards(query));
|
} else {
|
||||||
} else {
|
// Forwards the FindCommandRequest as is to a single shard so that limit and skip can
|
||||||
// Forwards the FindCommandRequest as is to a single shard so that limit and skip can
|
// be applied on mongod.
|
||||||
// be applied on mongod.
|
return query.getFindCommandRequest();
|
||||||
findCommand = std::make_unique<FindCommandRequest>(query.getFindCommandRequest());
|
}
|
||||||
}
|
}();
|
||||||
|
|
||||||
// Reset the input request's generic arguments and only set the ones needed for the query.
|
// Reset the input request's generic arguments and only set the ones needed for the query.
|
||||||
// TODO: SERVER-90827 Only reset arguments not suitable for passing through to shards.
|
// TODO: SERVER-90827 Only reset arguments not suitable for passing through to shards.
|
||||||
GenericArguments args;
|
GenericArguments args;
|
||||||
std::swap(findCommand->getGenericArguments(), args);
|
std::swap(findCommand.getGenericArguments(), args);
|
||||||
findCommand->setUnwrappedReadPref(std::move(args.getUnwrappedReadPref()));
|
findCommand.setUnwrappedReadPref(std::move(args.getUnwrappedReadPref()));
|
||||||
findCommand->setMaxTimeMS(args.getMaxTimeMS());
|
findCommand.setMaxTimeMS(args.getMaxTimeMS());
|
||||||
findCommand->setReadConcern(std::move(args.getReadConcern()));
|
findCommand.setReadConcern(std::move(args.getReadConcern()));
|
||||||
|
|
||||||
auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx);
|
auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx);
|
||||||
if (readConcernArgs.wasAtClusterTimeSelected()) {
|
if (readConcernArgs.wasAtClusterTimeSelected()) {
|
||||||
// If mongos selected atClusterTime or received it from client, transmit it to shard.
|
// If mongos selected atClusterTime or received it from client, transmit it to shard.
|
||||||
findCommand->setReadConcern(readConcernArgs);
|
findCommand.setReadConcern(readConcernArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
query.getExpCtx()->initializeReferencedSystemVariables();
|
query.getExpCtx()->initializeReferencedSystemVariables();
|
||||||
|
|
||||||
// Replace the 'letParams' expressions with their values.
|
// Replace the 'letParams' expressions with their values.
|
||||||
if (auto letParams = findCommand->getLet()) {
|
if (auto letParams = findCommand.getLet()) {
|
||||||
const auto& vars = query.getExpCtx()->variables;
|
const auto& vars = query.getExpCtx()->variables;
|
||||||
const auto& vps = query.getExpCtx()->variablesParseState;
|
const auto& vps = query.getExpCtx()->variablesParseState;
|
||||||
findCommand->setLet(vars.toBSON(vps, *letParams));
|
findCommand.setLet(vars.toBSON(vps, *letParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExpressionContext may contain previously looked up query settings. Propagate it to the
|
// ExpressionContext may contain previously looked up query settings. Propagate it to the
|
||||||
// shards.
|
// shards.
|
||||||
if (!query_settings::isDefault(query.getExpCtx()->getQuerySettings())) {
|
if (!query_settings::isDefault(query.getExpCtx()->getQuerySettings())) {
|
||||||
findCommand->setQuerySettings(query.getExpCtx()->getQuerySettings());
|
findCommand.setQuerySettings(query.getExpCtx()->getQuerySettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request metrics if necessary.
|
// Request metrics if necessary.
|
||||||
|
|
@ -205,7 +205,7 @@ std::unique_ptr<FindCommandRequest> makeFindCommandForShards(OperationContext* o
|
||||||
// rate) dictates we should gather metrics, or the user sent the flag to us.
|
// rate) dictates we should gather metrics, or the user sent the flag to us.
|
||||||
auto origValue = query.getFindCommandRequest().getIncludeQueryStatsMetrics();
|
auto origValue = query.getFindCommandRequest().getIncludeQueryStatsMetrics();
|
||||||
if (origValue.value_or(false) || requestQueryStatsFromRemotes) {
|
if (origValue.value_or(false) || requestQueryStatsFromRemotes) {
|
||||||
findCommand->setIncludeQueryStatsMetrics(true);
|
findCommand.setIncludeQueryStatsMetrics(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,79 +214,16 @@ std::unique_ptr<FindCommandRequest> makeFindCommandForShards(OperationContext* o
|
||||||
// necessarily want to forward all transaction arguments directly from the input request since
|
// necessarily want to forward all transaction arguments directly from the input request since
|
||||||
// we may have already started a transaction for internal purposes (e.g. FLE does this).
|
// we may have already started a transaction for internal purposes (e.g. FLE does this).
|
||||||
if (auto& lsid = opCtx->getLogicalSessionId()) {
|
if (auto& lsid = opCtx->getLogicalSessionId()) {
|
||||||
findCommand->setLsid(generic_argument_util::toLogicalSessionFromClient(*lsid));
|
findCommand.setLsid(generic_argument_util::toLogicalSessionFromClient(*lsid));
|
||||||
}
|
}
|
||||||
findCommand->setTxnNumber(opCtx->getTxnNumber());
|
findCommand.setTxnNumber(opCtx->getTxnNumber());
|
||||||
findCommand->setClientOperationKey(opKey);
|
findCommand.setClientOperationKey(opKey);
|
||||||
|
|
||||||
return findCommand;
|
return isRawDataOperation(opCtx) && findCommand.getNamespaceOrUUID().isNamespaceString() &&
|
||||||
}
|
findCommand.getNamespaceOrUUID().nss().isTimeseriesBucketsCollection()
|
||||||
|
? rewriteCommandForRawDataOperation<FindCommandRequest>(
|
||||||
/**
|
findCommand.toBSON(), findCommand.getNamespaceOrUUID().nss().coll())
|
||||||
* Constructs the shard requests (ShardId, BSONObj) pairs for the find command by attaching the
|
: findCommand.toBSON();
|
||||||
* shardVersion, txnNumber and sampleId if necessary.
|
|
||||||
*/
|
|
||||||
std::vector<AsyncRequestsSender::Request> constructRequestsForShards(
|
|
||||||
OperationContext* opCtx,
|
|
||||||
const CollectionRoutingInfo& cri,
|
|
||||||
const std::set<ShardId>& shardIds,
|
|
||||||
const CanonicalQuery& query,
|
|
||||||
const boost::optional<UUID> sampleId,
|
|
||||||
bool requestQueryStatsFromRemotes,
|
|
||||||
const auto& opKey) {
|
|
||||||
// Choose the shard to sample the query on if needed.
|
|
||||||
const auto sampleShardId = sampleId
|
|
||||||
? boost::make_optional(analyze_shard_key::getRandomShardId(shardIds))
|
|
||||||
: boost::none;
|
|
||||||
|
|
||||||
// Helper methods for appending additional attributes to the shard command.
|
|
||||||
auto appendVersions = [&](const auto& shardId, auto& cmdBuilder) {
|
|
||||||
if (cri.hasRoutingTable()) {
|
|
||||||
appendShardVersion(cmdBuilder, cri.getShardVersion(shardId));
|
|
||||||
} else if (!query.nss().isOnInternalDb()) {
|
|
||||||
appendShardVersion(cmdBuilder, ShardVersion::UNTRACKED());
|
|
||||||
appendDbVersionIfPresent(cmdBuilder, cri.getDbVersion());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto appendSampleId = [&](const auto& shardId, auto& cmdBuilder) {
|
|
||||||
if (shardId == sampleShardId) {
|
|
||||||
analyze_shard_key::appendSampleId(&cmdBuilder, *sampleId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructs the shard request by appending additional attributes to the serialized
|
|
||||||
// 'findCommandToForward'.
|
|
||||||
const auto findCommandToForward = makeFindCommandForShards(
|
|
||||||
opCtx, shardIds, query, sampleId, requestQueryStatsFromRemotes, opKey);
|
|
||||||
|
|
||||||
auto shardRegistry = Grid::get(opCtx)->shardRegistry();
|
|
||||||
auto makeShardRequest = [&](const auto& shardId) {
|
|
||||||
const auto shard = uassertStatusOK(shardRegistry->getShard(opCtx, shardId));
|
|
||||||
tassert(11052355,
|
|
||||||
"Expected either non-config shard or valid connection string for the config shard",
|
|
||||||
!shard->isConfig() || shard->getConnString());
|
|
||||||
|
|
||||||
BSONObjBuilder cmdBuilder;
|
|
||||||
findCommandToForward->serialize(&cmdBuilder);
|
|
||||||
appendVersions(shardId, cmdBuilder);
|
|
||||||
appendSampleId(shardId, cmdBuilder);
|
|
||||||
|
|
||||||
auto cmdObj = isRawDataOperation(opCtx) &&
|
|
||||||
findCommandToForward->getNamespaceOrUUID().isNamespaceString() &&
|
|
||||||
findCommandToForward->getNamespaceOrUUID().nss().isTimeseriesBucketsCollection()
|
|
||||||
? rewriteCommandForRawDataOperation<FindCommandRequest>(
|
|
||||||
cmdBuilder.obj(), findCommandToForward->getNamespaceOrUUID().nss().coll())
|
|
||||||
: cmdBuilder.obj();
|
|
||||||
|
|
||||||
return AsyncRequestsSender::Request(shardId, std::move(cmdObj), std::move(shard));
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<AsyncRequestsSender::Request> requests;
|
|
||||||
requests.reserve(shardIds.size());
|
|
||||||
std::transform(
|
|
||||||
shardIds.begin(), shardIds.end(), std::back_inserter(requests), makeShardRequest);
|
|
||||||
return requests;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateNumHostsTargetedMetrics(OperationContext* opCtx,
|
void updateNumHostsTargetedMetrics(OperationContext* opCtx,
|
||||||
|
|
@ -306,7 +243,6 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
|
||||||
RoutingContext& routingCtx,
|
RoutingContext& routingCtx,
|
||||||
const CanonicalQuery& query,
|
const CanonicalQuery& query,
|
||||||
const ReadPreferenceSetting& readPref,
|
const ReadPreferenceSetting& readPref,
|
||||||
const boost::optional<UUID> sampleId,
|
|
||||||
std::vector<BSONObj>* results,
|
std::vector<BSONObj>* results,
|
||||||
bool* partialResultsReturned) {
|
bool* partialResultsReturned) {
|
||||||
const auto& findCommand = query.getFindCommandRequest();
|
const auto& findCommand = query.getFindCommandRequest();
|
||||||
|
|
@ -401,8 +337,10 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
|
||||||
// shards, attaching the shardVersion and session info, if necessary. Attach our own
|
// shards, attaching the shardVersion and session info, if necessary. Attach our own
|
||||||
// OperationKey as well so establishCursors won't copy each request.
|
// OperationKey as well so establishCursors won't copy each request.
|
||||||
std::vector<OperationKey> opKeys{UUID::gen()};
|
std::vector<OperationKey> opKeys{UUID::gen()};
|
||||||
auto requests = constructRequestsForShards(
|
const auto findCommandToForward = makeFindCommandForShards(
|
||||||
opCtx, cri, shardIds, query, sampleId, requestQueryStatsFromRemotes, opKeys.front());
|
opCtx, shardIds, query, requestQueryStatsFromRemotes, opKeys.front());
|
||||||
|
auto requests = buildVersionedRequests(
|
||||||
|
opCtx, query.nss(), cri, shardIds, findCommandToForward, /*eligibleForSampling=*/true);
|
||||||
|
|
||||||
// The call to establishCursors has its own timeout mechanism that is controlled by the
|
// The call to establishCursors has its own timeout mechanism that is controlled by the
|
||||||
// opCtx, so we don't expect runWithDeadline to throw a timeout at this level. We use
|
// opCtx, so we don't expect runWithDeadline to throw a timeout at this level. We use
|
||||||
|
|
@ -852,12 +790,6 @@ void ClusterFind::runQuery(OperationContext* opCtx,
|
||||||
use the classic encoding method by default. */
|
use the classic encoding method by default. */
|
||||||
canonical_query_encoder::encodeClassic(*query));
|
canonical_query_encoder::encodeClassic(*query));
|
||||||
|
|
||||||
// Try to generate a sample id for this query here instead of inside
|
|
||||||
// 'runQueryWithoutRetrying()' since it is incorrect to generate multiple sample ids
|
|
||||||
// for a single query.
|
|
||||||
const auto sampleId = analyze_shard_key::tryGenerateSampleId(
|
|
||||||
opCtx, query->nss(), analyze_shard_key::SampledCommandNameEnum::kFind);
|
|
||||||
|
|
||||||
// If this is a viewless timeseries namespace, run the equivalent aggregation (which
|
// If this is a viewless timeseries namespace, run the equivalent aggregation (which
|
||||||
// writes its own cursor response into 'result') and short-circuit the normal find
|
// writes its own cursor response into 'result') and short-circuit the normal find
|
||||||
// path.
|
// path.
|
||||||
|
|
@ -889,13 +821,8 @@ void ClusterFind::runQuery(OperationContext* opCtx,
|
||||||
|
|
||||||
// Do the work to generate the first batch of results. This blocks waiting to
|
// Do the work to generate the first batch of results. This blocks waiting to
|
||||||
// get responses from the shard(s).
|
// get responses from the shard(s).
|
||||||
auto cursorId = runQueryWithoutRetrying(opCtx,
|
auto cursorId = runQueryWithoutRetrying(
|
||||||
routingCtx,
|
opCtx, routingCtx, *query, readPref, &batch, &partialResultsReturned);
|
||||||
*query,
|
|
||||||
readPref,
|
|
||||||
sampleId,
|
|
||||||
&batch,
|
|
||||||
&partialResultsReturned);
|
|
||||||
CursorResponseBuilder::Options options;
|
CursorResponseBuilder::Options options;
|
||||||
options.isInitialResponse = true;
|
options.isInitialResponse = true;
|
||||||
if (!opCtx->inMultiDocumentTransaction()) {
|
if (!opCtx->inMultiDocumentTransaction()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue