summaryrefslogtreecommitdiff
path: root/src/mongo/s/commands
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/s/commands
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (diff)
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0' with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/s/commands')
-rw-r--r--src/mongo/s/commands/SConscript5
-rw-r--r--src/mongo/s/commands/cluster_coll_stats_cmd.cpp6
-rw-r--r--src/mongo/s/commands/cluster_collection_mod_cmd.cpp14
-rw-r--r--src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp13
-rw-r--r--src/mongo/s/commands/cluster_count_cmd.cpp12
-rw-r--r--src/mongo/s/commands/cluster_create_indexes_cmd.cpp8
-rw-r--r--src/mongo/s/commands/cluster_data_size_cmd.cpp6
-rw-r--r--src/mongo/s/commands/cluster_distinct_cmd.cpp8
-rw-r--r--src/mongo/s/commands/cluster_drop_collection_cmd.cpp8
-rw-r--r--src/mongo/s/commands/cluster_filemd5_cmd.cpp4
-rw-r--r--src/mongo/s/commands/cluster_find_and_modify_cmd.cpp84
-rw-r--r--src/mongo/s/commands/cluster_find_cmd.h43
-rw-r--r--src/mongo/s/commands/cluster_fle2_compact_cmd.cpp1
-rw-r--r--src/mongo/s/commands/cluster_fsync_cmd.cpp68
-rw-r--r--src/mongo/s/commands/cluster_fsync_unlock_cmd.cpp134
-rw-r--r--src/mongo/s/commands/cluster_fsync_unlock_cmd.idl42
-rw-r--r--src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp5
-rw-r--r--src/mongo/s/commands/cluster_hello_cmd.cpp10
-rw-r--r--src/mongo/s/commands/cluster_index_filter_cmd.cpp4
-rw-r--r--src/mongo/s/commands/cluster_map_reduce_agg.cpp6
-rw-r--r--src/mongo/s/commands/cluster_move_range_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_plan_cache_clear_cmd.cpp4
-rw-r--r--src/mongo/s/commands/cluster_profile_cmd.cpp4
-rw-r--r--src/mongo/s/commands/cluster_rename_collection_cmd.cpp31
-rw-r--r--src/mongo/s/commands/cluster_set_free_monitoring_cmd.cpp75
-rw-r--r--src/mongo/s/commands/cluster_set_index_commit_quorum_cmd.cpp6
-rw-r--r--src/mongo/s/commands/cluster_validate_cmd.cpp6
-rw-r--r--src/mongo/s/commands/cluster_write_cmd.cpp40
-rw-r--r--src/mongo/s/commands/strategy.cpp102
-rw-r--r--src/mongo/s/commands/strategy.h4
30 files changed, 258 insertions, 497 deletions
diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript
index 237324eb92a..be0eb7d5203 100644
--- a/src/mongo/s/commands/SConscript
+++ b/src/mongo/s/commands/SConscript
@@ -53,8 +53,6 @@ env.Library(
'cluster_find_cmd_s.cpp',
'cluster_fle2_compact_cmd.cpp',
'cluster_fsync_cmd.cpp',
- 'cluster_fsync_unlock_cmd.cpp',
- 'cluster_fsync_unlock_cmd.idl',
'cluster_ftdc_commands.cpp',
'cluster_get_cluster_parameter_cmd.cpp',
'cluster_get_last_error_cmd.cpp',
@@ -86,6 +84,7 @@ env.Library(
'cluster_set_allow_migrations_cmd.cpp',
'cluster_set_cluster_parameter_cmd.cpp',
'cluster_set_feature_compatibility_version_cmd.cpp',
+ 'cluster_set_free_monitoring_cmd.cpp' if get_option("enable-free-mon") == 'on' else [],
'cluster_set_index_commit_quorum_cmd.cpp',
'cluster_set_user_write_block_mode_command.cpp',
'cluster_shard_collection_cmd.cpp',
@@ -103,7 +102,6 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/api_parameters',
'$BUILD_DIR/mongo/db/auth/auth_checks',
- '$BUILD_DIR/mongo/db/catalog/collection_uuid_mismatch_info',
'$BUILD_DIR/mongo/db/change_stream_options_manager',
'$BUILD_DIR/mongo/db/commands/cluster_server_parameter_cmds_idl',
'$BUILD_DIR/mongo/db/commands/core',
@@ -132,7 +130,6 @@ env.Library(
'$BUILD_DIR/mongo/db/query/command_request_response',
'$BUILD_DIR/mongo/db/query/cursor_response_idl',
'$BUILD_DIR/mongo/db/query/map_reduce_output_format',
- '$BUILD_DIR/mongo/db/query/query_shape/query_shape',
'$BUILD_DIR/mongo/db/read_write_concern_defaults',
'$BUILD_DIR/mongo/db/repl/hello_auth',
'$BUILD_DIR/mongo/db/repl/hello_command',
diff --git a/src/mongo/s/commands/cluster_coll_stats_cmd.cpp b/src/mongo/s/commands/cluster_coll_stats_cmd.cpp
index d3067b4769e..f85ae09aeb2 100644
--- a/src/mongo/s/commands/cluster_coll_stats_cmd.cpp
+++ b/src/mongo/s/commands/cluster_coll_stats_cmd.cpp
@@ -232,10 +232,8 @@ public:
opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(cmdObjToSend)),
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
- {} /*query*/,
- {} /*collation*/,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ {},
+ {});
BSONObjBuilder shardStats;
std::map<std::string, long long> counts;
diff --git a/src/mongo/s/commands/cluster_collection_mod_cmd.cpp b/src/mongo/s/commands/cluster_collection_mod_cmd.cpp
index 42e318aaa57..d295ca18c71 100644
--- a/src/mongo/s/commands/cluster_collection_mod_cmd.cpp
+++ b/src/mongo/s/commands/cluster_collection_mod_cmd.cpp
@@ -33,7 +33,6 @@
#include "mongo/db/auth/authorization_checks.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/catalog/collection_uuid_mismatch_info.h"
#include "mongo/db/coll_mod_gen.h"
#include "mongo/db/coll_mod_reply_validation.h"
#include "mongo/db/commands.h"
@@ -94,17 +93,8 @@ public:
"namespace"_attr = nss,
"command"_attr = redact(cmdObj));
- auto swDbInfo = Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, cmd.getDbName());
- if (swDbInfo == ErrorCodes::NamespaceNotFound) {
- uassert(CollectionUUIDMismatchInfo(cmd.getDbName().toString(),
- *cmd.getCollectionUUID(),
- nss.coll().toString(),
- boost::none),
- "Database does not exist",
- !cmd.getCollectionUUID());
- }
- const auto dbInfo = uassertStatusOK(swDbInfo);
-
+ const auto dbInfo =
+ uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, cmd.getDbName()));
ShardsvrCollMod collModCommand(nss);
collModCommand.setCollModRequest(cmd.getCollModRequest());
auto cmdResponse =
diff --git a/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp b/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp
index c6206bce5be..8c657bc453f 100644
--- a/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp
+++ b/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp
@@ -51,17 +51,8 @@ bool nonShardedCollectionCommandPassthrough(OperationContext* opCtx,
str::stream() << "Can't do command: " << cmdName << " on a sharded collection",
!cm.isSharded());
- auto responses = scatterGatherVersionedTargetByRoutingTable(opCtx,
- dbName,
- nss,
- cm,
- cmdObj,
- ReadPreferenceSetting::get(opCtx),
- retryPolicy,
- {} /*query*/,
- {} /*collation*/,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ auto responses = scatterGatherVersionedTargetByRoutingTable(
+ opCtx, dbName, nss, cm, cmdObj, ReadPreferenceSetting::get(opCtx), retryPolicy, {}, {});
invariant(responses.size() == 1);
const auto cmdResponse = uassertStatusOK(std::move(responses.front().swResponse));
diff --git a/src/mongo/s/commands/cluster_count_cmd.cpp b/src/mongo/s/commands/cluster_count_cmd.cpp
index 94e6c7c0eee..48545c7c0d7 100644
--- a/src/mongo/s/commands/cluster_count_cmd.cpp
+++ b/src/mongo/s/commands/cluster_count_cmd.cpp
@@ -131,9 +131,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
countRequest.getQuery(),
- collation,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ collation);
} catch (const ExceptionFor<ErrorCodes::CommandOnShardedViewNotSupportedOnMongod>& ex) {
// Rewrite the count command as an aggregation.
auto countRequest = CountCommandRequest::parse(IDLParserErrorContext("count"), cmdObj);
@@ -237,9 +235,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
targetingQuery,
- targetingCollation,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ targetingCollation);
} catch (const ExceptionFor<ErrorCodes::CommandOnShardedViewNotSupportedOnMongod>& ex) {
CountCommandRequest countRequest(NamespaceStringOrUUID(NamespaceString{}));
try {
@@ -288,14 +284,14 @@ private:
BSONElement l = cmd["limit"];
if (s.isNumber()) {
- num = num - s.safeNumberLong();
+ num = num - s.numberLong();
if (num < 0) {
num = 0;
}
}
if (l.isNumber()) {
- auto limit = l.safeNumberLong();
+ long long limit = l.numberLong();
if (limit < 0) {
limit = -limit;
}
diff --git a/src/mongo/s/commands/cluster_create_indexes_cmd.cpp b/src/mongo/s/commands/cluster_create_indexes_cmd.cpp
index 8f4928444c4..8c4c8af8784 100644
--- a/src/mongo/s/commands/cluster_create_indexes_cmd.cpp
+++ b/src/mongo/s/commands/cluster_create_indexes_cmd.cpp
@@ -89,6 +89,8 @@ public:
"namespace"_attr = nss,
"command"_attr = redact(cmdObj));
+ cluster::createDatabase(opCtx, dbName);
+
auto targeter = ChunkManagerTargeter(opCtx, nss);
auto routingInfo = targeter.getRoutingInfo();
auto cmdToBeSent = cmdObj;
@@ -106,10 +108,8 @@ public:
applyReadWriteConcern(opCtx, this, cmdToBeSent)),
ReadPreferenceSetting(ReadPreference::PrimaryOnly),
Shard::RetryPolicy::kNoRetry,
- BSONObj() /*query*/,
- BSONObj() /*collation*/,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ BSONObj() /* query */,
+ BSONObj() /* collation */);
std::string errmsg;
const bool ok =
diff --git a/src/mongo/s/commands/cluster_data_size_cmd.cpp b/src/mongo/s/commands/cluster_data_size_cmd.cpp
index 1c87c6a98f0..7d645d1a51c 100644
--- a/src/mongo/s/commands/cluster_data_size_cmd.cpp
+++ b/src/mongo/s/commands/cluster_data_size_cmd.cpp
@@ -85,10 +85,8 @@ public:
opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(cmdObj)),
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
- {} /*query*/,
- {} /*collation*/,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ {},
+ {});
// yes these are doubles...
double size = 0;
diff --git a/src/mongo/s/commands/cluster_distinct_cmd.cpp b/src/mongo/s/commands/cluster_distinct_cmd.cpp
index f34377258e4..70ae5f4b671 100644
--- a/src/mongo/s/commands/cluster_distinct_cmd.cpp
+++ b/src/mongo/s/commands/cluster_distinct_cmd.cpp
@@ -132,9 +132,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
targetingQuery,
- targetingCollation,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ targetingCollation);
} catch (const ExceptionFor<ErrorCodes::CommandOnShardedViewNotSupportedOnMongod>& ex) {
auto parsedDistinct = ParsedDistinct::parse(
opCtx, ex->getNamespace(), cmdObj, ExtensionsCallbackNoop(), true);
@@ -219,9 +217,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
query,
- collation,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ collation);
} catch (const ExceptionFor<ErrorCodes::CommandOnShardedViewNotSupportedOnMongod>& ex) {
auto parsedDistinct = ParsedDistinct::parse(
opCtx, ex->getNamespace(), cmdObj, ExtensionsCallbackNoop(), true);
diff --git a/src/mongo/s/commands/cluster_drop_collection_cmd.cpp b/src/mongo/s/commands/cluster_drop_collection_cmd.cpp
index 40e9196371f..e16f473ab3c 100644
--- a/src/mongo/s/commands/cluster_drop_collection_cmd.cpp
+++ b/src/mongo/s/commands/cluster_drop_collection_cmd.cpp
@@ -33,7 +33,6 @@
#include "mongo/base/status.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/catalog/collection_uuid_mismatch_info.h"
#include "mongo/db/commands.h"
#include "mongo/db/drop_gen.h"
#include "mongo/db/operation_context.h"
@@ -117,13 +116,6 @@ public:
// Ensure our reply conforms to the IDL-defined reply structure.
return DropReply::parse({"drop"}, resultObj);
} catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) {
- uassert(CollectionUUIDMismatchInfo(request().getDbName().toString(),
- *request().getCollectionUUID(),
- request().getNamespace().coll().toString(),
- boost::none),
- "Database does not exist",
- !request().getCollectionUUID());
-
// If the namespace isn't found, treat the drop as a success but inform about the
// failure.
DropReply reply;
diff --git a/src/mongo/s/commands/cluster_filemd5_cmd.cpp b/src/mongo/s/commands/cluster_filemd5_cmd.cpp
index 3248d9ce0ba..d351a7be7a3 100644
--- a/src/mongo/s/commands/cluster_filemd5_cmd.cpp
+++ b/src/mongo/s/commands/cluster_filemd5_cmd.cpp
@@ -98,9 +98,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
routingQuery,
- CollationSpec::kSimpleSpec,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ CollationSpec::kSimpleSpec);
invariant(shardResults.size() == 1);
const auto shardResponse = uassertStatusOK(std::move(shardResults[0].swResponse));
uassertStatusOK(shardResponse.status);
diff --git a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
index 195adef15e2..740d1561487 100644
--- a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
+++ b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
@@ -69,8 +69,6 @@
namespace mongo {
namespace {
-constexpr size_t kMaxDatabaseCreationAttempts = 3u;
-
const ReadPreferenceSetting kPrimaryOnlyReadPreference(ReadPreference::PrimaryOnly);
const char kLegacyRuntimeConstantsField[] = "runtimeConstants";
@@ -307,27 +305,6 @@ void handleWouldChangeOwningShardErrorTransactionLegacy(OperationContext* opCtx,
}
}
-ShardId targetSingleShard(boost::intrusive_ptr<ExpressionContext> expCtx,
- const ChunkManager& cm,
- const BSONObj& query,
- const BSONObj& collation) {
- std::set<ShardId> shardIds;
-
- // For now, set bypassIsFieldHashedCheck to be true in order to skip the
- // isFieldHashedCheck in the special case where _id is hashed and used as the shard
- // key. This means that we always assume that a findAndModify request using _id is
- // targetable to a single shard.
- cm.getShardIdsForQuery(expCtx, query, collation, &shardIds, true);
-
- uassert(ErrorCodes::ShardKeyNotFound,
- str::stream() << "Query with sharded findAndModify expected to only target one "
- "shard, but the query targeted "
- << shardIds.size() << " shard(s)",
- shardIds.size() == 1);
-
- return *shardIds.begin();
-}
-
class FindAndModifyCmd : public BasicCommand {
public:
FindAndModifyCmd()
@@ -415,14 +392,12 @@ public:
const BSONObj collation = getCollation(cmdObj);
const auto let = getLet(cmdObj);
const auto rc = getLegacyRuntimeConstants(cmdObj);
- ShardId shardId;
- {
- auto expCtx = makeExpressionContextWithDefaultsForTargeter(
- opCtx, nss, collation, verbosity, let, rc);
- shardId = targetSingleShard(expCtx, cm, query, collation);
- }
+ const BSONObj shardKey =
+ getShardKey(opCtx, cm, nss, query, collation, verbosity, let, rc);
+ const auto chunk = cm.findIntersectingChunk(shardKey, collation);
- shard = uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, shardId));
+ shard = uassertStatusOK(
+ Grid::get(opCtx)->shardRegistry()->getShard(opCtx, chunk.getShardId()));
} else {
shard =
uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, cm.dbPrimary()));
@@ -484,50 +459,31 @@ public:
// Collect metrics.
_updateMetrics.collectMetrics(cmdObj);
- const auto cm = [&]() {
- size_t attempts = 1u;
- while (true) {
- try {
- // Technically, findAndModify should only be creating database if upsert is
- // true, but this would require that the parsing be pulled into this function.
- cluster::createDatabase(opCtx, nss.db());
- return uassertStatusOK(getCollectionRoutingInfoForTxnCmd(opCtx, nss));
- } catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) {
- LOGV2_INFO(
- 8584300,
- "Failed initialization of routing info because the database has been "
- "concurrently dropped",
- logAttrs(nss),
- "attemptNumber"_attr = attempts,
- "maxAttempts"_attr = kMaxDatabaseCreationAttempts);
-
- if (attempts++ >= kMaxDatabaseCreationAttempts) {
- // The maximum number of attempts has been reached, so the procedure fails
- // as it could be a logical error. At this point, it is unlikely that the
- // error is caused by concurrent drop database operations.
- throw;
- }
- }
- }
- }();
+ // Technically, findAndModify should only be creating database if upsert is true, but this
+ // would require that the parsing be pulled into this function.
+ cluster::createDatabase(opCtx, nss.db());
// Append mongoS' runtime constants to the command object before forwarding it to the shard.
auto cmdObjForShard = appendLegacyRuntimeConstantsToCommandObject(opCtx, cmdObj);
+ const auto cm = uassertStatusOK(getCollectionRoutingInfoForTxnCmd(opCtx, nss));
if (cm.isSharded()) {
const BSONObj query = cmdObjForShard.getObjectField("query");
const BSONObj collation = getCollation(cmdObjForShard);
const auto let = getLet(cmdObjForShard);
const auto rc = getLegacyRuntimeConstants(cmdObjForShard);
- ShardId shardId;
- {
- auto expCtx = makeExpressionContextWithDefaultsForTargeter(
- opCtx, nss, collation, boost::none, let, rc);
- shardId = targetSingleShard(expCtx, cm, query, collation);
- }
+ const BSONObj shardKey =
+ getShardKey(opCtx, cm, nss, query, collation, boost::none, let, rc);
+
+ // For now, set bypassIsFieldHashedCheck to be true in order to skip the
+ // isFieldHashedCheck in the special case where _id is hashed and used as the shard key.
+ // This means that we always assume that a findAndModify request using _id is targetable
+ // to a single shard.
+ auto chunk = cm.findIntersectingChunk(shardKey, collation, true);
+
_runCommand(opCtx,
- shardId,
- cm.getVersion(shardId),
+ chunk.getShardId(),
+ cm.getVersion(chunk.getShardId()),
boost::none,
nss,
applyReadWriteConcern(opCtx, this, cmdObjForShard),
diff --git a/src/mongo/s/commands/cluster_find_cmd.h b/src/mongo/s/commands/cluster_find_cmd.h
index 6476d883200..87d25934d0c 100644
--- a/src/mongo/s/commands/cluster_find_cmd.h
+++ b/src/mongo/s/commands/cluster_find_cmd.h
@@ -38,9 +38,6 @@
#include "mongo/db/fle_crud.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
#include "mongo/db/query/cursor_response.h"
-#include "mongo/db/query/query_shape/query_shape.h"
-#include "mongo/db/query/query_stats/find_key.h"
-#include "mongo/db/query/query_stats/query_stats.h"
#include "mongo/db/stats/counters.h"
#include "mongo/db/views/resolved_view.h"
#include "mongo/rpc/get_status_from_command_result.h"
@@ -155,9 +152,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
findCommand->getFilter(),
- findCommand->getCollation(),
- findCommand->getLet(),
- findCommand->getLegacyRuntimeConstants());
+ findCommand->getCollation());
millisElapsed = timer.millis();
const char* mongosStageName =
@@ -204,23 +199,21 @@ public:
Impl::checkCanRunHere(opCtx);
- auto&& parsedFindResult = uassertStatusOK(parsed_find_command::parse(
- opCtx,
- _parseCmdObjectToFindCommandRequest(opCtx, ns(), _request.body),
- ExtensionsCallbackNoop(),
- MatchExpressionParser::kAllowAllSpecialFeatures));
- auto& expCtx = parsedFindResult.first;
- auto& parsedFind = parsedFindResult.second;
-
- if (!_didDoFLERewrite) {
- query_stats::registerRequest(opCtx, expCtx->ns, [&]() {
- // This callback is either never invoked or invoked
- // immediately within registerRequest, so
- // use-after-move of parsedFind isn't an issue.
- return std::make_unique<query_stats::FindKey>(expCtx, *parsedFind);
- });
- }
- auto cq = uassertStatusOK(CanonicalQuery::canonicalize(expCtx, std::move(parsedFind)));
+ ON_BLOCK_EXIT([opCtx] {
+ Grid::get(opCtx)->catalogCache()->checkAndRecordOperationBlockedByRefresh(
+ opCtx, mongo::LogicalOp::opQuery);
+ });
+
+ auto findCommand = _parseCmdObjectToFindCommandRequest(opCtx, ns(), _request.body);
+
+ const boost::intrusive_ptr<ExpressionContext> expCtx;
+ auto cq = uassertStatusOK(
+ CanonicalQuery::canonicalize(opCtx,
+ std::move(findCommand),
+ false, /* isExplain */
+ expCtx,
+ ExtensionsCallbackNoop(),
+ MatchExpressionParser::kAllowAllSpecialFeatures));
try {
// Do the work to generate the first batch of results. This blocks waiting to get
@@ -274,7 +267,7 @@ public:
* were supplied with the command, and sets the constant runtime values that will be
* forwarded to each shard.
*/
- std::unique_ptr<FindCommandRequest> _parseCmdObjectToFindCommandRequest(
+ static std::unique_ptr<FindCommandRequest> _parseCmdObjectToFindCommandRequest(
OperationContext* opCtx, NamespaceString nss, BSONObj cmdObj) {
auto findCommand = query_request_helper::makeFromFindCommand(
std::move(cmdObj),
@@ -301,7 +294,6 @@ public:
invariant(findCommand->getNamespaceOrUUID().nss());
processFLEFindS(
opCtx, findCommand->getNamespaceOrUUID().nss().get(), findCommand.get());
- _didDoFLERewrite = true;
}
return findCommand;
@@ -309,7 +301,6 @@ public:
const OpMsgRequest& _request;
const StringData _dbName;
- bool _didDoFLERewrite{false};
};
};
diff --git a/src/mongo/s/commands/cluster_fle2_compact_cmd.cpp b/src/mongo/s/commands/cluster_fle2_compact_cmd.cpp
index 7abae202f17..b1cecbf555e 100644
--- a/src/mongo/s/commands/cluster_fle2_compact_cmd.cpp
+++ b/src/mongo/s/commands/cluster_fle2_compact_cmd.cpp
@@ -32,7 +32,6 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/fle2_compact_gen.h"
-#include "mongo/db/curop.h"
#include "mongo/s/cluster_commands_helpers.h"
#include "mongo/s/grid.h"
diff --git a/src/mongo/s/commands/cluster_fsync_cmd.cpp b/src/mongo/s/commands/cluster_fsync_cmd.cpp
index 55316c964ac..e82469acee3 100644
--- a/src/mongo/s/commands/cluster_fsync_cmd.cpp
+++ b/src/mongo/s/commands/cluster_fsync_cmd.cpp
@@ -31,18 +31,10 @@
#include "mongo/client/read_preference.h"
#include "mongo/client/remote_command_targeter.h"
-#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
-#include "mongo/db/operation_context.h"
-#include "mongo/db/service_context.h"
#include "mongo/s/client/shard.h"
#include "mongo/s/client/shard_registry.h"
-#include "mongo/s/cluster_commands_helpers.h"
#include "mongo/s/grid.h"
-#include "mongo/s/sharding_feature_flags_gen.h"
-#include "mongo/util/assert_util.h"
-
-#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand
namespace mongo {
namespace {
@@ -75,47 +67,53 @@ public:
out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
}
- void unlockLockedShards(OperationContext* opCtx, const std::string& dbname) {
-
- auto request = OpMsgRequest::fromDBAndBody(dbname, BSON("fsyncUnlock" << 1));
- auto response = CommandHelpers::runCommandDirectly(opCtx, request);
- }
-
bool errmsgRun(OperationContext* opCtx,
const std::string& dbname,
const BSONObj& cmdObj,
std::string& errmsg,
BSONObjBuilder& result) override {
-
- BSONObj fsyncCmdObj = cmdObj;
if (cmdObj["lock"].trueValue()) {
- auto forBackupField = BSON("forBackup" << true);
- fsyncCmdObj = fsyncCmdObj.addFields(forBackupField);
+ errmsg = "can't do lock through mongos";
+ return false;
}
- auto shardResults = scatterGatherUnversionedTargetConfigServerAndShards(
- opCtx,
- dbname,
- applyReadWriteConcern(
- opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(fsyncCmdObj)),
- ReadPreferenceSetting(ReadPreference::PrimaryOnly),
- Shard::RetryPolicy::kIdempotent);
+ BSONObjBuilder sub;
- BSONObjBuilder rawResult;
- const auto response = appendRawResponses(opCtx, &errmsg, &rawResult, shardResults);
+ bool ok = true;
+
+ auto const shardRegistry = Grid::get(opCtx)->shardRegistry();
+ const auto shardIds = shardRegistry->getAllShardIdsNoReload();
+
+ for (const ShardId& shardId : shardIds) {
+ auto shardStatus = shardRegistry->getShard(opCtx, shardId);
+ if (!shardStatus.isOK()) {
+ continue;
+ }
+ const auto s = shardStatus.getValue();
+
+ auto response = uassertStatusOK(s->runCommandWithFixedRetryAttempts(
+ opCtx,
+ ReadPreferenceSetting{ReadPreference::PrimaryOnly},
+ "admin",
+ BSON("fsync" << 1),
+ Shard::RetryPolicy::kIdempotent));
+ uassertStatusOK(response.commandStatus);
+ BSONObj x = std::move(response.response);
+
+ sub.append(s->getId().toString(), x);
+
+ if (!x["ok"].trueValue()) {
+ ok = false;
+ errmsg = x["errmsg"].String();
+ }
+ }
// This field has had dummy value since MMAP went away. It is undocumented.
// Maintaining it so as not to cause unnecessary user pain across upgrades.
result.append("numFiles", 1);
- result.append("all", rawResult.obj());
- if (!response.responseOK) {
- if (cmdObj["lock"].trueValue()) {
- unlockLockedShards(opCtx, dbname);
- }
- return false;
- }
+ result.append("all", sub.obj());
- return true;
+ return ok;
}
} clusterFsyncCmd;
diff --git a/src/mongo/s/commands/cluster_fsync_unlock_cmd.cpp b/src/mongo/s/commands/cluster_fsync_unlock_cmd.cpp
deleted file mode 100644
index 5275298a7bb..00000000000
--- a/src/mongo/s/commands/cluster_fsync_unlock_cmd.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * Copyright (C) 2023-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/client/read_preference.h"
-#include "mongo/client/remote_command_targeter.h"
-#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/commands.h"
-#include "mongo/s/async_requests_sender.h"
-#include "mongo/s/client/shard.h"
-#include "mongo/s/client/shard_registry.h"
-#include "mongo/s/cluster_commands_helpers.h"
-#include "mongo/s/commands/cluster_fsync_unlock_cmd_gen.h"
-#include "mongo/s/grid.h"
-#include "mongo/s/sharding_feature_flags_gen.h"
-
-#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand
-
-namespace mongo {
-
-namespace {
-class FsyncUnlockCommand : public TypedCommand<FsyncUnlockCommand> {
-public:
- using Request = ClusterFsyncUnlock;
-
-
- class Invocation final : public InvocationBase {
- public:
- using InvocationBase::InvocationBase;
-
- /**
- * Intermediate wrapper to interface with ReplyBuilderInterface.
- */
- class Response {
- public:
- Response(BSONObj obj) : _obj(std::move(obj)) {}
-
- void serialize(BSONObjBuilder* builder) const {
- builder->appendElements(_obj);
- }
-
- private:
- const BSONObj _obj;
- };
-
- Response typedRun(OperationContext* opCtx) {
- BSONObj fsyncUnlockCmdObj = BSON("fsyncUnlock" << 1);
-
- auto responses = scatterGatherUnversionedTargetConfigServerAndShards(
- opCtx,
- NamespaceString::kAdminDb,
- applyReadWriteConcern(
- opCtx,
- this,
- CommandHelpers::filterCommandRequestForPassthrough(fsyncUnlockCmdObj)),
- ReadPreferenceSetting::get(opCtx),
- Shard::RetryPolicy::kIdempotent);
-
- BSONObjBuilder result;
- std::string errmsg;
- const auto rawResponsesResult = appendRawResponses(opCtx, &errmsg, &result, responses);
-
- if (!errmsg.empty()) {
- CommandHelpers::appendSimpleCommandStatus(
- result, rawResponsesResult.responseOK, errmsg);
- }
-
- return Response(result.obj());
- }
-
- private:
- NamespaceString ns() const override {
- return {};
- }
-
- bool supportsWriteConcern() const override {
- return false;
- }
-
- void doCheckAuthorization(OperationContext* opCtx) const override {
- uassert(ErrorCodes::Unauthorized,
- "Unauthorized",
- AuthorizationSession::get(opCtx->getClient())
- ->isAuthorizedForActionsOnResource(ResourcePattern::forExactNamespace(ns()),
- ActionType::fsyncUnlock));
- }
- };
-
- AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
- return AllowedOnSecondary::kAlways;
- }
-
- bool maintenanceOk() const override {
- return false;
- }
-
- bool adminOnly() const override {
- return true;
- }
-
- std::string help() const override {
- return "invoke fsync unlock on all shards belonging to the cluster";
- }
-} fsyncUnlockCmd;
-
-} // namespace
-} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_fsync_unlock_cmd.idl b/src/mongo/s/commands/cluster_fsync_unlock_cmd.idl
deleted file mode 100644
index c0d1be0aa0c..00000000000
--- a/src/mongo/s/commands/cluster_fsync_unlock_cmd.idl
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2023-present MongoDB, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the Server Side Public License, version 1,
-# as published by MongoDB, Inc.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# Server Side Public License for more details.
-#
-# You should have received a copy of the Server Side Public License
-# along with this program. If not, see
-# <http://www.mongodb.com/licensing/server-side-public-license>.
-#
-# As a special exception, the copyright holders give permission to link the
-# code of portions of this program with the OpenSSL library under certain
-# conditions as described in each individual source file and distribute
-# linked combinations including the program with the OpenSSL library. You
-# must comply with the Server Side Public License in all respects for
-# all of the code used other than as permitted herein. If you modify file(s)
-# with this exception, you may extend this exception to your version of the
-# file(s), but you are not obligated to do so. If you do not wish to do so,
-# delete this exception statement from your version. If you delete this
-# exception statement from all source files in the program, then also delete
-# it in the license file.
-#
-
-global:
- cpp_namespace: "mongo"
-
-imports:
- - "mongo/idl/basic_types.idl"
-
-commands:
- clusterFsyncUnlock:
- description: "The command for calling fsync unlock on all shards of a cluster."
- command_name: fsyncUnlock
- cpp_name: clusterFsyncUnlock
- strict: false
- namespace: ignored
- api_version: ""
diff --git a/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp b/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
index 4b6d49ebae1..1058e6ebafd 100644
--- a/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
+++ b/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
@@ -66,11 +66,6 @@ public:
using InvocationBase::InvocationBase;
Reply typedRun(OperationContext* opCtx) {
- uassert(ErrorCodes::UnknownFeatureCompatibilityVersion,
- "FCV is not yet initialized, retry the command after FCV initialization has "
- "completed",
- serverGlobalParams.featureCompatibility.isVersionInitialized());
-
uassert(
ErrorCodes::IllegalOperation,
"featureFlagClusterWideConfig not enabled",
diff --git a/src/mongo/s/commands/cluster_hello_cmd.cpp b/src/mongo/s/commands/cluster_hello_cmd.cpp
index 13b199f8ad3..5600a29661d 100644
--- a/src/mongo/s/commands/cluster_hello_cmd.cpp
+++ b/src/mongo/s/commands/cluster_hello_cmd.cpp
@@ -133,12 +133,6 @@ public:
// "hello" is exempt from error code rewrites.
rpc::RewriteStateChangeErrors::setEnabled(opCtx, false);
- // Negotiate compressors before logging metadata so we can include the result in the log
- // line.
- auto result = replyBuilder->getBodyBuilder();
- MessageCompressorManager::forSession(opCtx->getClient()->session())
- .serverNegotiate(cmd.getCompression(), &result);
-
auto client = opCtx->getClient();
if (ClientMetadata::tryFinalize(client)) {
audit::logClientMetadata(client);
@@ -172,6 +166,7 @@ public:
!clientTopologyVersion && !maxAwaitTimeMS);
}
+ auto result = replyBuilder->getBodyBuilder();
const auto* mongosTopCoord = MongosTopologyCoordinator::get(opCtx);
auto mongosHelloResponse =
@@ -224,6 +219,9 @@ public:
sp->append(opCtx, result, kAutomationServiceDescriptorFieldName);
}
+ MessageCompressorManager::forSession(opCtx->getClient()->session())
+ .serverNegotiate(cmd.getCompression(), &result);
+
if (opCtx->isExhaust()) {
LOGV2_DEBUG(23872, 3, "Using exhaust for hello protocol");
diff --git a/src/mongo/s/commands/cluster_index_filter_cmd.cpp b/src/mongo/s/commands/cluster_index_filter_cmd.cpp
index 48aec39e5cb..f6c5bd37777 100644
--- a/src/mongo/s/commands/cluster_index_filter_cmd.cpp
+++ b/src/mongo/s/commands/cluster_index_filter_cmd.cpp
@@ -104,9 +104,7 @@ public:
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
query,
- CollationSpec::kSimpleSpec,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ CollationSpec::kSimpleSpec);
// Sort shard responses by shard id.
std::sort(shardResponses.begin(),
diff --git a/src/mongo/s/commands/cluster_map_reduce_agg.cpp b/src/mongo/s/commands/cluster_map_reduce_agg.cpp
index 746ba39c7bc..52a61ab9325 100644
--- a/src/mongo/s/commands/cluster_map_reduce_agg.cpp
+++ b/src/mongo/s/commands/cluster_map_reduce_agg.cpp
@@ -187,7 +187,6 @@ bool runAggregationMapReduce(OperationContext* opCtx,
cm,
involvedNamespaces,
false, // hasChangeStream
- false, // startsWithDocuments
true, // allowedToPassthrough
false); // perShardCursor
try {
@@ -231,15 +230,14 @@ bool runAggregationMapReduce(OperationContext* opCtx,
namespaces,
privileges,
&tempResults,
- false, // hasChangeStream
- false)); // startsWithDocuments
+ false)); // hasChangeStream
break;
}
case cluster_aggregation_planner::AggregationTargeter::TargetingPolicy::
kSpecificShardOnly: {
// It should not be possible to pass $_passthroughToShard to a map reduce command.
- MONGO_UNREACHABLE_TASSERT(6273805);
+ MONGO_UNREACHABLE_TASSERT(6273803);
}
}
} catch (DBException& e) {
diff --git a/src/mongo/s/commands/cluster_move_range_cmd.cpp b/src/mongo/s/commands/cluster_move_range_cmd.cpp
index fd2f77ea9f5..c06ca4a5c47 100644
--- a/src/mongo/s/commands/cluster_move_range_cmd.cpp
+++ b/src/mongo/s/commands/cluster_move_range_cmd.cpp
@@ -100,7 +100,7 @@ public:
uassert(ErrorCodes::Unauthorized,
"Unauthorized",
AuthorizationSession::get(opCtx->getClient())
- ->isAuthorizedForActionsOnResource(ResourcePattern::forExactNamespace(ns()),
+ ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
ActionType::moveChunk));
}
};
diff --git a/src/mongo/s/commands/cluster_plan_cache_clear_cmd.cpp b/src/mongo/s/commands/cluster_plan_cache_clear_cmd.cpp
index e3411fbda2c..96499720ea6 100644
--- a/src/mongo/s/commands/cluster_plan_cache_clear_cmd.cpp
+++ b/src/mongo/s/commands/cluster_plan_cache_clear_cmd.cpp
@@ -110,9 +110,7 @@ bool ClusterPlanCacheClearCmd::run(OperationContext* opCtx,
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
query,
- CollationSpec::kSimpleSpec,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ CollationSpec::kSimpleSpec);
// Sort shard responses by shard id.
std::sort(shardResponses.begin(),
diff --git a/src/mongo/s/commands/cluster_profile_cmd.cpp b/src/mongo/s/commands/cluster_profile_cmd.cpp
index 022b44011c0..c2564c19b1d 100644
--- a/src/mongo/s/commands/cluster_profile_cmd.cpp
+++ b/src/mongo/s/commands/cluster_profile_cmd.cpp
@@ -33,7 +33,6 @@
#include "mongo/db/commands.h"
#include "mongo/db/commands/profile_common.h"
#include "mongo/db/commands/profile_gen.h"
-#include "mongo/db/commands/set_profiling_filter_globally_cmd.h"
#include "mongo/db/profile_filter_impl.h"
namespace mongo {
@@ -54,6 +53,7 @@ protected:
OperationContext* opCtx,
const std::string& dbName,
const ProfileCmdRequest& request) const final {
+ invariant(!opCtx->lockState()->isW());
const auto profilingLevel = request.getCommandParameter();
@@ -85,7 +85,5 @@ protected:
} profileCmd;
-SetProfilingFilterGloballyCmd setProfilingFilterGloballyCmd;
-
} // namespace
} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_rename_collection_cmd.cpp b/src/mongo/s/commands/cluster_rename_collection_cmd.cpp
index a5c3d9d385c..4d4d88907a6 100644
--- a/src/mongo/s/commands/cluster_rename_collection_cmd.cpp
+++ b/src/mongo/s/commands/cluster_rename_collection_cmd.cpp
@@ -32,7 +32,6 @@
#include "mongo/platform/basic.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/catalog/collection_uuid_mismatch_info.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/rename_collection_common.h"
#include "mongo/db/commands/rename_collection_gen.h"
@@ -75,21 +74,6 @@ public:
"Can't rename a collection to itself",
fromNss != toNss);
- if (fromNss.isTimeseriesBucketsCollection()) {
- uassert(
- ErrorCodes::IllegalOperation,
- "Renaming system.buckets collections is not allowed",
- AuthorizationSession::get(opCtx->getClient())
- ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
- ActionType::setUserWriteBlockMode));
-
- uassert(ErrorCodes::IllegalOperation,
- str::stream()
- << "Cannot rename time-series buckets collection {" << fromNss.ns()
- << "} to a non-time-series buckets namespace {" << toNss.ns() << "}",
- toNss.isTimeseriesBucketsCollection());
- }
-
RenameCollectionRequest renameCollReq(request().getTo());
renameCollReq.setStayTemp(request().getStayTemp());
renameCollReq.setExpectedSourceUUID(request().getCollectionUUID());
@@ -106,22 +90,9 @@ public:
ShardsvrRenameCollection renameCollRequest(fromNss);
renameCollRequest.setDbName(fromNss.db());
renameCollRequest.setRenameCollectionRequest(renameCollReq);
- renameCollRequest.setAllowEncryptedCollectionRename(
- AuthorizationSession::get(opCtx->getClient())
- ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
- ActionType::setUserWriteBlockMode));
auto catalogCache = Grid::get(opCtx)->catalogCache();
- auto swDbInfo = Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, fromNss.db());
- if (swDbInfo == ErrorCodes::NamespaceNotFound) {
- uassert(CollectionUUIDMismatchInfo(fromNss.db().toString(),
- *request().getCollectionUUID(),
- fromNss.coll().toString(),
- boost::none),
- "Database does not exist",
- !request().getCollectionUUID());
- }
- const auto dbInfo = uassertStatusOK(swDbInfo);
+ const auto dbInfo = uassertStatusOK(catalogCache->getDatabase(opCtx, fromNss.db()));
auto cri = uassertStatusOK(catalogCache->getCollectionRoutingInfo(opCtx, fromNss));
auto shard = uassertStatusOK(
diff --git a/src/mongo/s/commands/cluster_set_free_monitoring_cmd.cpp b/src/mongo/s/commands/cluster_set_free_monitoring_cmd.cpp
new file mode 100644
index 00000000000..d54cd80b219
--- /dev/null
+++ b/src/mongo/s/commands/cluster_set_free_monitoring_cmd.cpp
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2018-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/commands.h"
+
+namespace mongo {
+namespace {
+
+class ClusterSetFreeMonitoring : public BasicCommand {
+public:
+ ClusterSetFreeMonitoring() : BasicCommand("setFreeMonitoring") {}
+
+ AllowedOnSecondary secondaryAllowed(ServiceContext*) const final {
+ return AllowedOnSecondary::kNever;
+ }
+
+ bool supportsWriteConcern(const BSONObj& cmd) const final {
+ return false;
+ }
+
+ std::string help() const final {
+ return "setFreeMonitoring command must be run against mongod instances";
+ }
+
+ Status checkAuthForCommand(Client* client,
+ const std::string& dbname,
+ const BSONObj& cmdObj) const final {
+ if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource(
+ ResourcePattern::forClusterResource(), ActionType::setFreeMonitoring)) {
+ return Status(ErrorCodes::Unauthorized, "Unauthorized");
+ }
+ return Status::OK();
+ }
+
+ bool run(OperationContext* opCtx,
+ const std::string& dbname,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) final {
+ uasserted(ErrorCodes::CommandFailed, help());
+ return true;
+ }
+
+} clusterSetFreeMonitoring;
+
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_set_index_commit_quorum_cmd.cpp b/src/mongo/s/commands/cluster_set_index_commit_quorum_cmd.cpp
index f494e41a6a6..8727a9da078 100644
--- a/src/mongo/s/commands/cluster_set_index_commit_quorum_cmd.cpp
+++ b/src/mongo/s/commands/cluster_set_index_commit_quorum_cmd.cpp
@@ -117,10 +117,8 @@ public:
opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(cmdObj)),
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kNotIdempotent,
- BSONObj() /*query*/,
- BSONObj() /*collation*/,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ BSONObj() /* query */,
+ BSONObj() /* collation */);
std::string errmsg;
const bool ok =
diff --git a/src/mongo/s/commands/cluster_validate_cmd.cpp b/src/mongo/s/commands/cluster_validate_cmd.cpp
index 285d23fc29d..52285704516 100644
--- a/src/mongo/s/commands/cluster_validate_cmd.cpp
+++ b/src/mongo/s/commands/cluster_validate_cmd.cpp
@@ -84,10 +84,8 @@ public:
opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(cmdObj)),
ReadPreferenceSetting::get(opCtx),
Shard::RetryPolicy::kIdempotent,
- {} /*query*/,
- {} /*collation*/,
- boost::none /*letParameters*/,
- boost::none /*runtimeConstants*/);
+ {},
+ {});
Status firstFailedShardStatus = Status::OK();
bool isValid = true;
diff --git a/src/mongo/s/commands/cluster_write_cmd.cpp b/src/mongo/s/commands/cluster_write_cmd.cpp
index 8590832acc6..10d04ba0b82 100644
--- a/src/mongo/s/commands/cluster_write_cmd.cpp
+++ b/src/mongo/s/commands/cluster_write_cmd.cpp
@@ -145,6 +145,11 @@ boost::optional<WouldChangeOwningShardInfo> getWouldChangeOwningShardErrorInfo(
void handleWouldChangeOwningShardErrorRetryableWrite(OperationContext* opCtx,
BatchedCommandRequest* request,
BatchedCommandResponse* response) {
+ // Strip write concern because this command will be sent as part of a
+ // transaction and the write concern has already been loaded onto the opCtx and
+ // will be picked up by the transaction API.
+ request->unsetWriteConcern();
+
// Strip runtime constants because they will be added again when the API sends this command
// through the service entry point.
request->unsetLegacyRuntimeConstants();
@@ -313,6 +318,11 @@ bool handleWouldChangeOwningShardError(OperationContext* opCtx,
auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx);
readConcernArgs = repl::ReadConcernArgs(repl::ReadConcernLevel::kLocalReadConcern);
+ // Ensure the retried operation does not include WC inside the transaction. The
+ // transaction commit will still use the WC, because it uses the WC from the opCtx
+ // (which has been set previously in Strategy).
+ request->unsetWriteConcern();
+
documentShardKeyUpdateUtil::startTransactionForShardKeyUpdate(opCtx);
// Clear the error details from the response object before sending the write again
response->unsetErrDetails();
@@ -497,6 +507,29 @@ bool ClusterWriteCmd::InvocationBase::runImpl(OperationContext* opCtx,
BatchWriteExecStats stats;
BatchedCommandResponse response;
+ // The batched request will only have WC if it was supplied by the client. Otherwise, the
+ // batched request should use the WC from the opCtx.
+ if (!batchedRequest.hasWriteConcern()) {
+ if (opCtx->getWriteConcern().usedDefaultConstructedWC) {
+ // Pass writeConcern: {}, rather than {w: 1, wtimeout: 0}, so as to not override the
+ // configsvr w:majority upconvert.
+ batchedRequest.setWriteConcern(BSONObj());
+ } else {
+ batchedRequest.setWriteConcern(opCtx->getWriteConcern().toBSON());
+ }
+ }
+
+ // Write ops are never allowed to have writeConcern inside transactions. Normally
+ // disallowing WC on non-terminal commands in a transaction is handled earlier, during
+ // command dispatch. However, if this is a regular write operation being automatically
+ // retried inside a transaction (such as changing a document's shard key across shards),
+ // then batchedRequest will have a writeConcern (added by the if() above) from when it was
+ // initially run outside a transaction. Thus it's necessary to unconditionally clear the
+ // writeConcern when in a transaction.
+ if (TransactionRouter::get(opCtx)) {
+ batchedRequest.unsetWriteConcern();
+ }
+
cluster::write(opCtx, batchedRequest, &stats, &response);
bool updatedShardKey = false;
@@ -522,17 +555,22 @@ bool ClusterWriteCmd::InvocationBase::runImpl(OperationContext* opCtx,
// TODO: increase opcounters by more than one
auto& debug = CurOp::get(opCtx)->debug();
+ auto catalogCache = Grid::get(opCtx)->catalogCache();
switch (_batchedRequest.getBatchType()) {
case BatchedCommandRequest::BatchType_Insert:
for (size_t i = 0; i < numAttempts; ++i) {
globalOpCounters.gotInsert();
}
+ catalogCache->checkAndRecordOperationBlockedByRefresh(opCtx,
+ mongo::LogicalOp::opInsert);
debug.additiveMetrics.ninserted = response.getN();
break;
case BatchedCommandRequest::BatchType_Update:
for (size_t i = 0; i < numAttempts; ++i) {
globalOpCounters.gotUpdate();
}
+ catalogCache->checkAndRecordOperationBlockedByRefresh(opCtx,
+ mongo::LogicalOp::opUpdate);
// The response.getN() count is the sum of documents matched and upserted.
if (response.isUpsertDetailsSet()) {
@@ -565,6 +603,8 @@ bool ClusterWriteCmd::InvocationBase::runImpl(OperationContext* opCtx,
for (size_t i = 0; i < numAttempts; ++i) {
globalOpCounters.gotDelete();
}
+ catalogCache->checkAndRecordOperationBlockedByRefresh(opCtx,
+ mongo::LogicalOp::opDelete);
debug.additiveMetrics.ndeleted = response.getN();
break;
}
diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp
index e12b3385a13..13d061e9e6d 100644
--- a/src/mongo/s/commands/strategy.cpp
+++ b/src/mongo/s/commands/strategy.cpp
@@ -426,6 +426,14 @@ public:
explicit RunInvocation(ParseAndRunCommand* parc) : _parc(parc) {}
+ ~RunInvocation() {
+ if (!_shouldAffectCommandCounter)
+ return;
+ auto opCtx = _parc->_rec->getOpCtx();
+ Grid::get(opCtx)->catalogCache()->checkAndRecordOperationBlockedByRefresh(
+ opCtx, mongo::LogicalOp::opCommand);
+ }
+
Future<void> run();
private:
@@ -434,6 +442,7 @@ private:
ParseAndRunCommand* const _parc;
boost::optional<RouterOperationContextSession> _routerSession;
+ bool _shouldAffectCommandCounter = false;
};
/*
@@ -698,53 +707,31 @@ Status ParseAndRunCommand::RunInvocation::_setup() {
(opCtx->getClient()->session() &&
(opCtx->getClient()->session()->getTags() & transport::Session::kInternalClient));
- bool canApplyDefaultWC = supportsWriteConcern &&
+ if (supportsWriteConcern && !clientSuppliedWriteConcern &&
(!TransactionRouter::get(opCtx) || isTransactionCommand(_parc->_commandName)) &&
- !opCtx->getClient()->isInDirectClient();
-
- if (canApplyDefaultWC) {
- auto getDefaultWC = ([&]() {
- auto rwcDefaults =
+ !opCtx->getClient()->isInDirectClient()) {
+ if (isInternalClient) {
+ uassert(
+ 5569900,
+ "received command without explicit writeConcern on an internalClient connection {}"_format(
+ redact(request.body.toString())),
+ request.body.hasField(WriteConcernOptions::kWriteConcernField));
+ } else {
+ // This command is not from a DBDirectClient or internal client, and supports WC, but
+ // wasn't given one - so apply the default, if there is one.
+ const auto rwcDefaults =
ReadWriteConcernDefaults::get(opCtx->getServiceContext()).getDefault(opCtx);
- auto wcDefault = rwcDefaults.getDefaultWriteConcern();
- const auto defaultWriteConcernSource = rwcDefaults.getDefaultWriteConcernSource();
- customDefaultWriteConcernWasApplied = defaultWriteConcernSource &&
- defaultWriteConcernSource == DefaultWriteConcernSourceEnum::kGlobal;
- return wcDefault;
- });
-
- if (!clientSuppliedWriteConcern) {
- if (isInternalClient) {
- uassert(
- 5569900,
- "received command without explicit writeConcern on an internalClient connection {}"_format(
- redact(request.body.toString())),
- request.body.hasField(WriteConcernOptions::kWriteConcernField));
- } else {
- // This command is not from a DBDirectClient or internal client, and supports WC,
- // but wasn't given one - so apply the default, if there is one.
- const auto wcDefault = getDefaultWC();
- // Default WC can be 'boost::none' if the implicit default is used and set to 'w:1'.
- if (wcDefault) {
- _parc->_wc = *wcDefault;
- LOGV2_DEBUG(22766,
- 2,
- "Applying default writeConcern on command",
- "command"_attr = request.getCommandName(),
- "writeConcern"_attr = *wcDefault);
- }
- }
- }
- // Client supplied a write concern object without 'w' field.
- else if (_parc->_wc->isExplicitWithoutWField()) {
- const auto wcDefault = getDefaultWC();
- // Default WC can be 'boost::none' if the implicit default is used and set to 'w:1'.
- if (wcDefault) {
- clientSuppliedWriteConcern = false;
- _parc->_wc->w = wcDefault->w;
- if (_parc->_wc->syncMode == WriteConcernOptions::SyncMode::UNSET) {
- _parc->_wc->syncMode = wcDefault->syncMode;
- }
+ if (const auto wcDefault = rwcDefaults.getDefaultWriteConcern()) {
+ _parc->_wc = *wcDefault;
+ const auto defaultWriteConcernSource = rwcDefaults.getDefaultWriteConcernSource();
+ customDefaultWriteConcernWasApplied = defaultWriteConcernSource &&
+ defaultWriteConcernSource == DefaultWriteConcernSourceEnum::kGlobal;
+ LOGV2_DEBUG(22766,
+ 2,
+ "Applying default writeConcern on {command} of {writeConcern}",
+ "Applying default writeConcern on command",
+ "command"_attr = request.getCommandName(),
+ "writeConcern"_attr = *wcDefault);
}
}
}
@@ -911,6 +898,7 @@ Status ParseAndRunCommand::RunInvocation::_setup() {
if (command->shouldAffectCommandCounter()) {
globalOpCounters.gotCommand();
+ _shouldAffectCommandCounter = true;
}
return Status::OK();
@@ -1048,21 +1036,10 @@ void ParseAndRunCommand::RunAndRetry::_onNeedRetargetting(Status& status) {
auto opCtx = _parc->_rec->getOpCtx();
const auto staleNs = staleInfo->getNss();
- const auto& originalNs = _parc->_invocation->ns();
auto catalogCache = Grid::get(opCtx)->catalogCache();
catalogCache->invalidateShardOrEntireCollectionEntryForShardedCollection(
staleNs, staleInfo->getVersionWanted(), staleInfo->getShardId());
- if ((staleNs.isTimeseriesBucketsCollection() || originalNs.isTimeseriesBucketsCollection()) &&
- staleNs != originalNs) {
- // A timeseries might've been created, so we need to invalidate the original namespace
- // version.
- Grid::get(opCtx)
- ->catalogCache()
- ->invalidateShardOrEntireCollectionEntryForShardedCollection(
- originalNs, boost::none, staleInfo->getShardId());
- }
-
catalogCache->setOperationShouldBlockBehindCatalogCacheRefresh(opCtx, true);
_checkRetryForTransaction(status);
@@ -1193,13 +1170,6 @@ public:
Future<DbResponse> run();
private:
- std::string _getDatabaseStringForLogging() const try {
- // `getDatabase` throws if the request doesn't have a '$db' field.
- return _rec->getRequest().getDatabase().toString();
- } catch (const DBException& ex) {
- return ex.toString();
- }
-
void _parseMessage();
Future<void> _execute();
@@ -1242,7 +1212,7 @@ Future<void> ClientCommand::_execute() {
3,
"Command begin db: {db} msg id: {headerId}",
"Command begin",
- "db"_attr = _getDatabaseStringForLogging(),
+ "db"_attr = _rec->getRequest().getDatabase().toString(),
"headerId"_attr = _rec->getMessage().header().getId());
return future_util::makeState<ParseAndRunCommand>(_rec, _errorBuilder)
@@ -1252,7 +1222,7 @@ Future<void> ClientCommand::_execute() {
3,
"Command end db: {db} msg id: {headerId}",
"Command end",
- "db"_attr = _getDatabaseStringForLogging(),
+ "db"_attr = _rec->getRequest().getDatabase().toString(),
"headerId"_attr = _rec->getMessage().header().getId());
})
.tapError([this](Status status) {
@@ -1261,7 +1231,7 @@ Future<void> ClientCommand::_execute() {
1,
"Exception thrown while processing command on {db} msg id: {headerId} {error}",
"Exception thrown while processing command",
- "db"_attr = _getDatabaseStringForLogging(),
+ "db"_attr = _rec->getRequest().getDatabase().toString(),
"headerId"_attr = _rec->getMessage().header().getId(),
"error"_attr = redact(status));
diff --git a/src/mongo/s/commands/strategy.h b/src/mongo/s/commands/strategy.h
index 73916229f7f..1e04130f657 100644
--- a/src/mongo/s/commands/strategy.h
+++ b/src/mongo/s/commands/strategy.h
@@ -41,8 +41,8 @@ public:
/**
* Executes a command from either OP_QUERY or OP_MSG wire protocols.
*
- * Catches StaleConfig errors and retries the command automatically after refreshing the
- * metadata for the failing namespace.
+ * Catches StaleConfigException errors and retries the command automatically after refreshing
+ * the metadata for the failing namespace.
*/
static Future<DbResponse> clientCommand(std::shared_ptr<RequestExecutionContext> rec);
};