summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/catalog/drop_indexes.cpp15
-rw-r--r--src/mongo/db/drop_indexes.idl37
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/shardsvr_drop_indexes_command.cpp220
-rw-r--r--src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp8
-rw-r--r--src/mongo/s/SConscript1
-rw-r--r--src/mongo/s/cluster_commands_helpers.cpp1
-rw-r--r--src/mongo/s/cluster_commands_helpers.h2
-rw-r--r--src/mongo/s/commands/cluster_drop_indexes_cmd.cpp110
-rw-r--r--src/mongo/s/request_types/sharded_ddl_commands.idl11
-rw-r--r--src/mongo/s/stale_shard_version_helpers.h8
11 files changed, 303 insertions, 111 deletions
diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp
index 200fdf8ed0f..2c10eb005c5 100644
--- a/src/mongo/db/catalog/drop_indexes.cpp
+++ b/src/mongo/db/catalog/drop_indexes.cpp
@@ -282,7 +282,8 @@ std::vector<UUID> abortActiveIndexBuilders(OperationContext* opCtx,
void dropReadyIndexes(OperationContext* opCtx,
Collection* collection,
const std::vector<std::string>& indexNames,
- DropIndexesReply* reply) {
+ DropIndexesReply* reply,
+ bool forceDropShardKeyIndex) {
invariant(opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_X));
if (indexNames.empty()) {
@@ -294,7 +295,7 @@ void dropReadyIndexes(OperationContext* opCtx,
CollectionShardingState::get(opCtx, collection->ns())->getCollectionDescription(opCtx);
if (indexNames.front() == "*") {
- if (collDescription.isSharded()) {
+ if (collDescription.isSharded() && !forceDropShardKeyIndex) {
indexCatalog->dropIndexes(
opCtx,
collection,
@@ -561,7 +562,8 @@ DropIndexesReply dropIndexes(OperationContext* opCtx,
// This is necessary to check shard version.
OldClientContext ctx(opCtx, (*collection)->ns().ns());
- dropReadyIndexes(opCtx, collection->getWritableCollection(opCtx), indexNames, &reply);
+ dropReadyIndexes(
+ opCtx, collection->getWritableCollection(opCtx), indexNames, &reply, false);
wunit.commit();
});
@@ -611,8 +613,11 @@ Status dropIndexesForApplyOps(OperationContext* opCtx,
OldClientContext ctx(opCtx, nss.ns());
DropIndexesReply ignoredReply;
- dropReadyIndexes(
- opCtx, collection.getWritableCollection(opCtx), swIndexNames.getValue(), &ignoredReply);
+ dropReadyIndexes(opCtx,
+ collection.getWritableCollection(opCtx),
+ swIndexNames.getValue(),
+ &ignoredReply,
+ true);
wunit.commit();
return Status::OK();
diff --git a/src/mongo/db/drop_indexes.idl b/src/mongo/db/drop_indexes.idl
index a8e60f78a9f..ad6d9283536 100644
--- a/src/mongo/db/drop_indexes.idl
+++ b/src/mongo/db/drop_indexes.idl
@@ -50,20 +50,9 @@ structs:
optional: true
unstable: false
-commands:
- dropIndexes:
- description: "Parser for the dropIndexes command"
- command_name: dropIndexes
- command_alias: deleteIndexes
- namespace: concatenate_with_db
- cpp_name: dropIndexes
- strict: true
- api_version: "1"
- access_check:
- simple:
- privilege:
- resource_pattern: exact_namespace
- action_type: dropIndex
+ DropIndexesRequest:
+ description: dropIndexes command request
+ strict: false
fields:
index:
description: An index name, or array of names, or "*" for all indexes, or an index
@@ -85,5 +74,23 @@ commands:
type: uuid
description: "The expected UUID of the collection."
optional: true
- unstable: true
+ unstable: true
+
+commands:
+ dropIndexes:
+ description: "Parser for the dropIndexes command"
+ command_name: dropIndexes
+ command_alias: deleteIndexes
+ namespace: concatenate_with_db
+ cpp_name: dropIndexes
+ strict: true
+ api_version: "1"
+ access_check:
+ simple:
+ privilege:
+ resource_pattern: exact_namespace
+ action_type: dropIndex
+ inline_chained_structs: true
+ chained_structs:
+ DropIndexesRequest: DropIndexesRequest
reply_type: DropIndexesReply
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript
index f6befa3d2c3..c1f953c72e0 100644
--- a/src/mongo/db/s/SConscript
+++ b/src/mongo/db/s/SConscript
@@ -416,6 +416,7 @@ env.Library(
'shardsvr_drop_collection_participant_command.cpp',
'shardsvr_drop_database_command.cpp',
'shardsvr_drop_database_participant_command.cpp',
+ 'shardsvr_drop_indexes_command.cpp',
'shardsvr_get_stats_for_balancing_command.cpp',
'shardsvr_merge_chunks_command.cpp',
'shardsvr_move_primary_command.cpp',
diff --git a/src/mongo/db/s/shardsvr_drop_indexes_command.cpp b/src/mongo/db/s/shardsvr_drop_indexes_command.cpp
new file mode 100644
index 00000000000..0c6d2d4260b
--- /dev/null
+++ b/src/mongo/db/s/shardsvr_drop_indexes_command.cpp
@@ -0,0 +1,220 @@
+/**
+ * Copyright (C) 2022-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.
+ */
+
+#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kSharding
+
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/catalog/collection_catalog.h"
+#include "mongo/db/commands.h"
+#include "mongo/db/curop.h"
+#include "mongo/db/s/database_sharding_state.h"
+#include "mongo/db/s/dist_lock_manager.h"
+#include "mongo/db/s/sharding_state.h"
+#include "mongo/db/timeseries/timeseries_commands_conversion_helper.h"
+#include "mongo/logv2/log.h"
+#include "mongo/s/chunk_manager_targeter.h"
+#include "mongo/s/cluster_commands_helpers.h"
+#include "mongo/s/grid.h"
+#include "mongo/s/request_types/sharded_ddl_commands_gen.h"
+#include "mongo/s/stale_shard_version_helpers.h"
+
+namespace mongo {
+namespace {
+
+struct StaleConfigRetryState {
+ std::set<ShardId> shardsWithSuccessResponses;
+ std::vector<AsyncRequestsSender::Response> shardSuccessResponses;
+};
+
+void updateStateForStaleConfigRetry(OperationContext* opCtx,
+ const RawResponsesResult& response,
+ StaleConfigRetryState* retryState) {
+ std::set<ShardId> okShardIds;
+ std::set_union(response.shardsWithSuccessResponses.begin(),
+ response.shardsWithSuccessResponses.end(),
+ retryState->shardsWithSuccessResponses.begin(),
+ retryState->shardsWithSuccessResponses.end(),
+ std::inserter(okShardIds, okShardIds.begin()));
+
+ retryState->shardsWithSuccessResponses = std::move(okShardIds);
+ retryState->shardSuccessResponses = std::move(response.successResponses);
+}
+
+class ShardsvrDropIndexesCommand final : public TypedCommand<ShardsvrDropIndexesCommand> {
+public:
+ using Request = ShardsvrDropIndexes;
+
+ bool skipApiVersionCheck() const override {
+ // Internal command (server to server).
+ return true;
+ }
+
+ std::string help() const override {
+ return "Internal command. Do not call directly. Drops indexes.";
+ }
+
+ bool adminOnly() const override {
+ return false;
+ }
+
+ AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
+ return AllowedOnSecondary::kNever;
+ }
+
+ 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);
+
+ private:
+ NamespaceString ns() const override {
+ return request().getNamespace();
+ }
+
+ bool supportsWriteConcern() const override {
+ return true;
+ }
+
+ void doCheckAuthorization(OperationContext* opCtx) const override {
+ uassert(ErrorCodes::Unauthorized,
+ "Unauthorized",
+ AuthorizationSession::get(opCtx->getClient())
+ ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal));
+ }
+ };
+
+} shardsvrDropIndexesCommand;
+
+ShardsvrDropIndexesCommand::Invocation::Response ShardsvrDropIndexesCommand::Invocation::typedRun(
+ OperationContext* opCtx) {
+ uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands());
+ CommandHelpers::uassertCommandRunWithMajority(Request::kCommandName, opCtx->getWriteConcern());
+
+ // Since this operation is not directly writing locally we need to force its db profile level
+ // increase in order to be logged in "<db>.system.profile".
+ CurOp::get(opCtx)->raiseDbProfileLevel(
+ CollectionCatalog::get(opCtx)->getDatabaseProfileLevel(ns().db()));
+
+ DropIndexes dropIdxCmd(ns());
+ dropIdxCmd.setDropIndexesRequest(request().getDropIndexesRequest());
+
+ const auto lockTimeout = [&]() -> Milliseconds {
+ if (auto sfp = globalFailPointRegistry().find("overrideDDLLockTimeout")->scoped();
+ MONGO_unlikely(sfp.isActive())) {
+ if (auto timeoutElem = sfp.getData()["timeoutMillisecs"]; timeoutElem.ok()) {
+ const auto timeoutMillisecs = Milliseconds(timeoutElem.safeNumberLong());
+ LOGV2(649100, "Overriding DDL lock timeout", "timeout"_attr = timeoutMillisecs);
+ return timeoutMillisecs;
+ }
+ }
+ return DistLockManager::kDefaultLockTimeout;
+ }();
+
+ auto distLockManager = DistLockManager::get(opCtx);
+ auto dbLocalLock = distLockManager->lockDirectLocally(opCtx, ns().db(), lockTimeout);
+
+ // Check under the dbLock if this is still the primary shard for the database
+ DatabaseShardingState::checkIsPrimaryShardForDb(opCtx, ns().db());
+
+ auto nsLocalLock = distLockManager->lockDirectLocally(opCtx, ns().ns(), lockTimeout);
+
+ StaleConfigRetryState retryState;
+ return shardVersionRetry(opCtx, Grid::get(opCtx)->catalogCache(), ns(), "dropIndexes", [&] {
+ // If the collection is sharded, we target only the primary shard and the shards that own
+ // chunks for the collection.
+ auto targeter = ChunkManagerTargeter(opCtx, ns());
+ auto routingInfo = targeter.getRoutingInfo();
+
+ auto cmdToBeSent = dropIdxCmd.toBSON({});
+ if (targeter.timeseriesNamespaceNeedsRewrite(ns())) {
+ cmdToBeSent =
+ timeseries::makeTimeseriesCommand(cmdToBeSent,
+ ns(),
+ DropIndexes::kCommandName,
+ DropIndexes::kIsTimeseriesNamespaceFieldName);
+ }
+
+ cmdToBeSent = CommandHelpers::filterCommandRequestForPassthrough(
+ CommandHelpers::appendMajorityWriteConcern(cmdToBeSent));
+
+ auto shardResponses =
+ scatterGatherVersionedTargetByRoutingTableNoThrowOnStaleShardVersionErrors(
+ opCtx,
+ ns().db(),
+ targeter.getNS(),
+ routingInfo,
+ retryState.shardsWithSuccessResponses,
+ applyReadWriteConcern(
+ opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(cmdToBeSent)),
+ ReadPreferenceSetting::get(opCtx),
+ Shard::RetryPolicy::kNotIdempotent,
+ BSONObj() /* query */,
+ BSONObj() /* collation */);
+
+ // Append responses we've received from previous retries of this operation due to a stale
+ // config error.
+ shardResponses.insert(shardResponses.end(),
+ retryState.shardSuccessResponses.begin(),
+ retryState.shardSuccessResponses.end());
+
+ std::string errmsg;
+ BSONObjBuilder output;
+ const auto aggregateResponse =
+ appendRawResponses(opCtx, &errmsg, &output, std::move(shardResponses));
+
+ // If we have a stale config error, update the success shards for the upcoming retry.
+ if (!aggregateResponse.responseOK && aggregateResponse.firstStaleConfigError) {
+ updateStateForStaleConfigRetry(opCtx, aggregateResponse, &retryState);
+ uassertStatusOK(*aggregateResponse.firstStaleConfigError);
+ }
+
+ CommandHelpers::appendSimpleCommandStatus(output, aggregateResponse.responseOK, errmsg);
+ return Response(output.obj());
+ });
+}
+
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
index abe386549c5..8b0a2f512b7 100644
--- a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
+++ b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
@@ -247,10 +247,14 @@ DropIndexes makeTimeseriesDropIndexesCommand(OperationContext* opCtx,
<< " Command request: " << redact(origCmd.toBSON({})),
bucketsIndexSpecWithStatus.isOK());
- return DropIndexes(ns, std::move(bucketsIndexSpecWithStatus.getValue()));
+ DropIndexes dropIndexCmd(ns);
+ dropIndexCmd.setDropIndexesRequest({std::move(bucketsIndexSpecWithStatus.getValue())});
+ return dropIndexCmd;
}
- return DropIndexes(ns, origIndex);
+ DropIndexes dropIndexCmd(ns);
+ dropIndexCmd.setDropIndexesRequest(origIndex);
+ return dropIndexCmd;
}
} // namespace mongo::timeseries
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 7432c3a3b86..f8ee64d895c 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -233,6 +233,7 @@ env.Library(
'$BUILD_DIR/mongo/db/commands/cluster_server_parameter_cmds_idl',
'$BUILD_DIR/mongo/db/commands/set_user_write_block_mode_idl',
'$BUILD_DIR/mongo/db/common',
+ '$BUILD_DIR/mongo/db/index_commands_idl',
'$BUILD_DIR/mongo/db/namespace_string',
'$BUILD_DIR/mongo/db/query/query_request',
'$BUILD_DIR/mongo/db/repl/optime',
diff --git a/src/mongo/s/cluster_commands_helpers.cpp b/src/mongo/s/cluster_commands_helpers.cpp
index 8a508f449f1..5c0469ab245 100644
--- a/src/mongo/s/cluster_commands_helpers.cpp
+++ b/src/mongo/s/cluster_commands_helpers.cpp
@@ -475,7 +475,6 @@ RawResponsesResult appendRawResponses(
std::string* errmsg,
BSONObjBuilder* output,
const std::vector<AsyncRequestsSender::Response>& shardResponses) {
-
std::vector<AsyncRequestsSender::Response> successARSResponses;
std::vector<std::pair<ShardId, BSONObj>> successResponsesReceived;
std::vector<std::pair<ShardId, Status>> shardNotFoundErrorsReceived;
diff --git a/src/mongo/s/cluster_commands_helpers.h b/src/mongo/s/cluster_commands_helpers.h
index 1a9428c5547..f342b7f799e 100644
--- a/src/mongo/s/cluster_commands_helpers.h
+++ b/src/mongo/s/cluster_commands_helpers.h
@@ -235,7 +235,7 @@ AsyncRequestsSender::Response executeCommandAgainstShardWithMinKeyChunk(
* string representation of all errors to 'errmsg.'
*
* ShardNotFound responses are not treated as errors if any shard returned success. We allow
- * ShardNotFound errors to be ignored as errors since this node may not heave realized that a
+ * ShardNotFound errors to be ignored as errors since this node may not have realized that a
* shard has been removed.
*
* Returns:
diff --git a/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp b/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp
index 24f2f507137..28e3e74e7e4 100644
--- a/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp
+++ b/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp
@@ -32,49 +32,17 @@
#include "mongo/platform/basic.h"
#include "mongo/db/commands.h"
-#include "mongo/db/drop_indexes_gen.h"
-#include "mongo/db/timeseries/timeseries_commands_conversion_helper.h"
#include "mongo/logv2/log.h"
#include "mongo/rpc/get_status_from_command_result.h"
-#include "mongo/s/chunk_manager_targeter.h"
#include "mongo/s/cluster_commands_helpers.h"
#include "mongo/s/grid.h"
+#include "mongo/s/request_types/sharded_ddl_commands_gen.h"
namespace mongo {
namespace {
constexpr auto kRawFieldName = "raw"_sd;
-struct StaleConfigRetryState {
- std::set<ShardId> shardsWithSuccessResponses;
- std::vector<AsyncRequestsSender::Response> shardSuccessResponses;
-};
-
-const OperationContext::Decoration<std::unique_ptr<StaleConfigRetryState>> staleConfigRetryState =
- OperationContext::declareDecoration<std::unique_ptr<StaleConfigRetryState>>();
-
-StaleConfigRetryState createAndRetrieveStateFromStaleConfigRetry(OperationContext* opCtx) {
- if (!staleConfigRetryState(opCtx)) {
- staleConfigRetryState(opCtx) = std::make_unique<StaleConfigRetryState>();
- }
-
- return *staleConfigRetryState(opCtx);
-}
-
-void updateStateForStaleConfigRetry(OperationContext* opCtx,
- const StaleConfigRetryState& retryState,
- const RawResponsesResult& response) {
- std::set<ShardId> okShardIds;
- std::set_union(response.shardsWithSuccessResponses.begin(),
- response.shardsWithSuccessResponses.end(),
- retryState.shardsWithSuccessResponses.begin(),
- retryState.shardsWithSuccessResponses.end(),
- std::inserter(okShardIds, okShardIds.begin()));
-
- staleConfigRetryState(opCtx)->shardsWithSuccessResponses = std::move(okShardIds);
- staleConfigRetryState(opCtx)->shardSuccessResponses = std::move(response.successResponses);
-}
-
class DropIndexesCmd : public BasicCommandWithRequestParser<DropIndexesCmd> {
public:
using Request = DropIndexes;
@@ -128,6 +96,15 @@ public:
const RequestParser& requestParser,
BSONObjBuilder& output) final {
auto nss = requestParser.request().getNamespace();
+
+ uassert(ErrorCodes::IllegalOperation,
+ "Cannot drop indexes in 'config' database in sharded cluster",
+ nss.db() != NamespaceString::kConfigDb);
+
+ uassert(ErrorCodes::IllegalOperation,
+ "Cannot drop indexes in 'admin' database in sharded cluster",
+ nss.db() != NamespaceString::kAdminDb);
+
LOGV2_DEBUG(22751,
1,
"dropIndexes: {namespace} cmd: {command}",
@@ -135,61 +112,24 @@ public:
"namespace"_attr = nss,
"command"_attr = redact(cmdObj));
- // dropIndexes can be retried on a stale config error. If a previous attempt already
- // successfully dropped the index on shards, those shards will return an IndexNotFound
- // error when retried. We instead maintain the record of shards that have already
- // successfully dropped the index, so that we don't try to contact those shards again
- // across stale config retries.
- const auto retryState = createAndRetrieveStateFromStaleConfigRetry(opCtx);
-
- // If the collection is sharded, we target only the primary shard and the shards that own
- // chunks for the collection.
- auto targeter = ChunkManagerTargeter(opCtx, nss);
- auto routingInfo = targeter.getRoutingInfo();
-
- auto cmdToBeSent = cmdObj;
- if (targeter.timeseriesNamespaceNeedsRewrite(nss)) {
- cmdToBeSent = timeseries::makeTimeseriesCommand(
- cmdToBeSent, nss, getName(), DropIndexes::kIsTimeseriesNamespaceFieldName);
- }
+ ShardsvrDropIndexes shardsvrDropIndexCmd(nss);
+ shardsvrDropIndexCmd.setDropIndexesRequest(requestParser.request().getDropIndexesRequest());
- auto shardResponses =
- scatterGatherVersionedTargetByRoutingTableNoThrowOnStaleShardVersionErrors(
- opCtx,
- nss.db(),
- targeter.getNS(),
- routingInfo,
- retryState.shardsWithSuccessResponses,
- applyReadWriteConcern(
- opCtx, this, CommandHelpers::filterCommandRequestForPassthrough(cmdToBeSent)),
- ReadPreferenceSetting::get(opCtx),
- Shard::RetryPolicy::kNotIdempotent,
- BSONObj() /* query */,
- BSONObj() /* collation */);
-
- // Append responses we've received from previous retries of this operation due to a stale
- // config error.
- shardResponses.insert(shardResponses.end(),
- retryState.shardSuccessResponses.begin(),
- retryState.shardSuccessResponses.end());
-
- std::string errmsg;
- const auto aggregateResponse =
- appendRawResponses(opCtx, &errmsg, &output, std::move(shardResponses));
-
- // If we have a stale config error, update the success shards for the upcoming retry.
- if (!aggregateResponse.responseOK && aggregateResponse.firstStaleConfigError) {
- updateStateForStaleConfigRetry(opCtx, retryState, aggregateResponse);
- uassertStatusOK(*aggregateResponse.firstStaleConfigError);
- }
+ const CachedDatabaseInfo dbInfo =
+ uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, dbName));
- CommandHelpers::appendSimpleCommandStatus(output, aggregateResponse.responseOK, errmsg);
+ auto cmdResponse = executeCommandAgainstDatabasePrimary(
+ opCtx,
+ dbName,
+ dbInfo,
+ CommandHelpers::appendMajorityWriteConcern(shardsvrDropIndexCmd.toBSON({}),
+ opCtx->getWriteConcern()),
+ ReadPreferenceSetting(ReadPreference::PrimaryOnly),
+ Shard::RetryPolicy::kNotIdempotent);
- if (aggregateResponse.responseOK) {
- LOGV2(5706401, "Indexes dropped", "namespace"_attr = nss);
- }
-
- return aggregateResponse.responseOK;
+ const auto remoteResponse = uassertStatusOK(cmdResponse.swResponse);
+ CommandHelpers::filterCommandReplyForPassthrough(remoteResponse.data, &output);
+ return true;
}
const AuthorizationContract* getAuthorizationContract() const final {
diff --git a/src/mongo/s/request_types/sharded_ddl_commands.idl b/src/mongo/s/request_types/sharded_ddl_commands.idl
index 8f40c11e835..2c86a3d199a 100644
--- a/src/mongo/s/request_types/sharded_ddl_commands.idl
+++ b/src/mongo/s/request_types/sharded_ddl_commands.idl
@@ -36,6 +36,7 @@ global:
imports:
- "mongo/db/commands/rename_collection.idl"
- "mongo/db/commands/set_user_write_block_mode.idl"
+ - "mongo/db/drop_indexes.idl"
- "mongo/db/drop_database.idl"
- "mongo/db/keypattern.idl"
- "mongo/db/coll_mod.idl"
@@ -395,6 +396,16 @@ commands:
Verifies that the shard key index has the same unique setting as the command.
type: optionalBool
+ _shardsvrDropIndexes:
+ description: "Parser for the _shardsvrDropIndexes command"
+ command_name: _shardsvrDropIndexes
+ cpp_name: ShardsvrDropIndexes
+ namespace: concatenate_with_db
+ api_version: ""
+ strict: false
+ chained_structs:
+ DropIndexesRequest: DropIndexesRequest
+
_configsvrCreateDatabase:
description: "The internal createDatabase command on the config server"
api_version: ""
diff --git a/src/mongo/s/stale_shard_version_helpers.h b/src/mongo/s/stale_shard_version_helpers.h
index c1c7e8443bc..a3771a41552 100644
--- a/src/mongo/s/stale_shard_version_helpers.h
+++ b/src/mongo/s/stale_shard_version_helpers.h
@@ -111,9 +111,13 @@ auto shardVersionRetry(ServiceContext* service,
_callbackFn = std::move(callbackFn),
executor,
cancelToken] {
- ThreadClient tc(taskDescription, service);
+ boost::optional<ThreadClient> threadClient;
+ if (!haveClient()) {
+ threadClient.emplace(taskDescription, service);
+ }
+
CancelableOperationContextFactory opCtxFactory(cancelToken, executor);
- auto cancelableOpCtx = opCtxFactory.makeOperationContext(tc.get());
+ auto cancelableOpCtx = opCtxFactory.makeOperationContext(&cc());
auto opCtx = cancelableOpCtx.get();
catalogCache->setOperationShouldBlockBehindCatalogCacheRefresh(opCtx, *numAttempts);