summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaume Moragues <jaume.moragues@mongodb.com>2020-11-25 09:38:55 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-25 10:16:39 +0000
commit4ff5abf776772827db06bcc941382e3822731d3a (patch)
treef64cdf63d70b398d11134d302df605d97ee42705
parent7b92716c97e05c09f624513b03bd3eb7663aa537 (diff)
downloadmongo-4ff5abf776772827db06bcc941382e3822731d3a.tar.gz
SERVER-52810 Create the _shardsvrDropDatabase command
-rw-r--r--jstests/core/views/views_all_commands.js1
-rw-r--r--jstests/replsets/db_reads_while_recovering_all_commands.js1
-rw-r--r--jstests/sharding/read_write_concern_defaults_application.js1
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/shardsvr_drop_database_command.cpp107
-rw-r--r--src/mongo/s/SConscript1
-rw-r--r--src/mongo/s/commands/cluster_drop_database_cmd.cpp63
-rw-r--r--src/mongo/s/request_types/sharded_ddl_commands.idl44
8 files changed, 196 insertions, 23 deletions
diff --git a/jstests/core/views/views_all_commands.js b/jstests/core/views/views_all_commands.js
index 125c9904e18..fe39fe6fc33 100644
--- a/jstests/core/views/views_all_commands.js
+++ b/jstests/core/views/views_all_commands.js
@@ -119,6 +119,7 @@ let viewsCommandTests = {
_shardsvrMovePrimary: {skip: isAnInternalCommand},
_shardsvrRenameCollection: {skip: isAnInternalCommand},
_shardsvrShardCollection: {skip: isAnInternalCommand},
+ _shardsvrDropDatabase: {skip: isAnInternalCommand},
_transferMods: {skip: isAnInternalCommand},
_vectorClockPersist: {skip: isAnInternalCommand},
abortTransaction: {skip: isUnrelated},
diff --git a/jstests/replsets/db_reads_while_recovering_all_commands.js b/jstests/replsets/db_reads_while_recovering_all_commands.js
index 1d91b91e00a..bbcc3a03db2 100644
--- a/jstests/replsets/db_reads_while_recovering_all_commands.js
+++ b/jstests/replsets/db_reads_while_recovering_all_commands.js
@@ -66,6 +66,7 @@ const allCommands = {
_shardsvrCloneCatalogData: {skip: isPrimaryOnly},
_shardsvrMovePrimary: {skip: isPrimaryOnly},
_shardsvrShardCollection: {skip: isPrimaryOnly},
+ _shardsvrDropDatabase: {skip: isPrimaryOnly},
_transferMods: {skip: isPrimaryOnly},
_vectorClockPersist: {skip: isPrimaryOnly},
abortTransaction: {skip: isPrimaryOnly},
diff --git a/jstests/sharding/read_write_concern_defaults_application.js b/jstests/sharding/read_write_concern_defaults_application.js
index 49dc5e526fb..0ba92d245fc 100644
--- a/jstests/sharding/read_write_concern_defaults_application.js
+++ b/jstests/sharding/read_write_concern_defaults_application.js
@@ -117,6 +117,7 @@ let testCases = {
_shardsvrMovePrimary: {skip: "internal command"},
_shardsvrRenameCollection: {skip: "internal command"},
_shardsvrShardCollection: {skip: "internal command"},
+ _shardsvrDropDatabase: {skip: "internal command"},
_transferMods: {skip: "internal command"},
_vectorClockPersist: {skip: "internal command"},
abortTransaction: {
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript
index 373be39e030..f554ffc9933 100644
--- a/src/mongo/db/s/SConscript
+++ b/src/mongo/db/s/SConscript
@@ -336,6 +336,7 @@ env.Library(
'set_shard_version_command.cpp',
'sharding_server_status.cpp',
'sharding_state_command.cpp',
+ 'shardsvr_drop_database_command.cpp',
'shardsvr_shard_collection.cpp',
'split_chunk_command.cpp',
'split_vector_command.cpp',
diff --git a/src/mongo/db/s/shardsvr_drop_database_command.cpp b/src/mongo/db/s/shardsvr_drop_database_command.cpp
new file mode 100644
index 00000000000..5d8095ce197
--- /dev/null
+++ b/src/mongo/db/s/shardsvr_drop_database_command.cpp
@@ -0,0 +1,107 @@
+/**
+ * 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.
+ */
+
+#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kSharding
+
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/commands.h"
+#include "mongo/db/drop_database_gen.h"
+#include "mongo/db/s/config/sharding_catalog_manager.h"
+#include "mongo/db/s/sharding_logging.h"
+#include "mongo/s/catalog/dist_lock_manager.h"
+#include "mongo/s/catalog/type_database.h"
+#include "mongo/s/catalog_cache.h"
+#include "mongo/s/grid.h"
+#include "mongo/s/request_types/sharded_ddl_commands_gen.h"
+#include "mongo/s/sharded_collections_ddl_parameters_gen.h"
+
+namespace mongo {
+namespace {
+
+class ShardsvrDropDatabaseCommand final : public TypedCommand<ShardsvrDropDatabaseCommand> {
+public:
+ bool acceptsAnyApiVersionParameters() const override {
+ return true;
+ }
+
+ AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
+ return Command::AllowedOnSecondary::kNever;
+ }
+
+ std::string help() const override {
+ return "Internal command, which is exported by the primary sharding server. Do not call "
+ "directly. Drops a database.";
+ }
+
+ using Request = ShardsvrDropDatabase;
+ using Response = DropDatabaseReply;
+
+ class Invocation final : public InvocationBase {
+ public:
+ using InvocationBase::InvocationBase;
+
+ Response typedRun(OperationContext* opCtx) {
+ uassert(ErrorCodes::IllegalOperation,
+ "_shardsvrDropDatabase can only be run on primary shard servers",
+ serverGlobalParams.clusterRole == ClusterRole::ShardServer);
+
+ const StringData dbName = request().getDbName();
+
+ const auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard();
+ auto cmdResponse = uassertStatusOK(configShard->runCommandWithFixedRetryAttempts(
+ opCtx,
+ ReadPreferenceSetting(ReadPreference::PrimaryOnly),
+ "admin",
+ CommandHelpers::appendMajorityWriteConcern(BSON("_configsvrDropDatabase" << dbName),
+ opCtx->getWriteConcern()),
+ Shard::RetryPolicy::kIdempotent));
+
+ uassertStatusOK(cmdResponse.commandStatus);
+
+ return Response::parse(IDLParserErrorContext("dropDatabase-reply"),
+ cmdResponse.response);
+ }
+
+ bool supportsWriteConcern() const override {
+ return true;
+ }
+
+ void doCheckAuthorization(OperationContext*) const override {}
+
+ /**
+ * The ns() for when Request's IDL specifies "namespace: concatenate_with_db".
+ */
+ NamespaceString ns() const override {
+ return {"", ""};
+ }
+ };
+} shardsvrDropDatabaseCommand;
+
+} // namespace
+} // namespace mongo \ No newline at end of file
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index bf4fc8cc3a6..29518c5d5ae 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -171,6 +171,7 @@ env.Library(
'request_types/reshard_collection.idl',
'request_types/set_shard_version_request.cpp',
'request_types/shard_collection.idl',
+ 'request_types/sharded_ddl_commands.idl',
'request_types/split_chunk_request_type.cpp',
'request_types/update_zone_key_range_request_type.cpp',
'request_types/wait_for_fail_point.idl',
diff --git a/src/mongo/s/commands/cluster_drop_database_cmd.cpp b/src/mongo/s/commands/cluster_drop_database_cmd.cpp
index f96a2cef9fc..3cb36fe8518 100644
--- a/src/mongo/s/commands/cluster_drop_database_cmd.cpp
+++ b/src/mongo/s/commands/cluster_drop_database_cmd.cpp
@@ -35,9 +35,12 @@
#include "mongo/db/commands.h"
#include "mongo/db/drop_database_gen.h"
#include "mongo/db/operation_context.h"
+#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/s/catalog_cache.h"
#include "mongo/s/client/shard_registry.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/util/scopeguard.h"
namespace mongo {
@@ -78,7 +81,6 @@ public:
uassert(ErrorCodes::IllegalOperation,
"Cannot drop the config database",
dbname != NamespaceString::kConfigDb);
-
uassert(ErrorCodes::IllegalOperation,
"Cannot drop the admin database",
dbname != NamespaceString::kAdminDb);
@@ -88,28 +90,43 @@ public:
"have to pass 1 as db parameter",
request.getCommandParameter() == 1);
- // Invalidate the database metadata so the next access kicks off a full reload, even if
- // sending the command to the config server fails due to e.g. a NetworkError.
- ON_BLOCK_EXIT([opCtx, dbname] { Grid::get(opCtx)->catalogCache()->purgeDatabase(dbname); });
-
- // Send _configsvrDropDatabase to the config server.
- auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard();
- auto cmdResponse = uassertStatusOK(configShard->runCommandWithFixedRetryAttempts(
- opCtx,
- ReadPreferenceSetting(ReadPreference::PrimaryOnly),
- "admin",
- CommandHelpers::appendMajorityWriteConcern(
- CommandHelpers::appendGenericCommandArgs(cmdObj,
- BSON("_configsvrDropDatabase" << dbname)),
- opCtx->getWriteConcern()),
- Shard::RetryPolicy::kIdempotent));
-
- // The cmdResponse status can be OK even if the config server replied ok: 0.
- uassertStatusOK(cmdResponse.commandStatus);
- auto reply = DropDatabaseReply::parse(IDLParserErrorContext("dropDatabase-reply"),
- cmdResponse.response);
- CommandHelpers::appendGenericReplyFields(cmdResponse.response, reply.toBSON(), &result);
- return true;
+ try {
+
+ const CachedDatabaseInfo dbInfo =
+ uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, dbname));
+
+ // Invalidate the database metadata so the next access kicks off a full reload, even if
+ // sending the command to the config server fails due to e.g. a NetworkError.
+ ON_BLOCK_EXIT(
+ [opCtx, dbname] { Grid::get(opCtx)->catalogCache()->purgeDatabase(dbname); });
+
+ // Send it to the primary shard
+ ShardsvrDropDatabase dropDatabaseCommand(1);
+ dropDatabaseCommand.setDbName(dbname);
+
+ auto cmdResponse = executeCommandAgainstDatabasePrimary(
+ opCtx,
+ dbname,
+ dbInfo,
+ CommandHelpers::appendMajorityWriteConcern(dropDatabaseCommand.toBSON({}),
+ opCtx->getWriteConcern()),
+ ReadPreferenceSetting(ReadPreference::PrimaryOnly),
+ Shard::RetryPolicy::kIdempotent);
+
+ const auto remoteResponse = uassertStatusOK(cmdResponse.swResponse);
+ uassertStatusOK(getStatusFromCommandResult(remoteResponse.data));
+
+ auto reply = DropDatabaseReply::parse(IDLParserErrorContext("dropDatabase-reply"),
+ remoteResponse.data);
+ CommandHelpers::appendGenericReplyFields(remoteResponse.data, reply.toBSON(), &result);
+
+ return true;
+ } catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) {
+ // If the namespace isn't found, treat the drop as a success but inform about the
+ // failure.
+ result.append("info", "database does not exist");
+ return true;
+ }
}
} clusterDropDatabaseCmd;
diff --git a/src/mongo/s/request_types/sharded_ddl_commands.idl b/src/mongo/s/request_types/sharded_ddl_commands.idl
new file mode 100644
index 00000000000..cf94288655b
--- /dev/null
+++ b/src/mongo/s/request_types/sharded_ddl_commands.idl
@@ -0,0 +1,44 @@
+# Copyright (C) 2020-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/db/drop_database.idl"
+ - "mongo/s/database_version.idl"
+
+commands:
+ _shardsvrDropDatabase:
+ description: "Parser for the shardDropDatabase command"
+ command_name: _shardsvrDropDatabase
+ namespace: type
+ type: safeInt64
+ cpp_name: ShardsvrDropDatabase
+ strict: true
+ reply_type: DropDatabaseReply \ No newline at end of file