summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheahuychou Mao <cheahuychou.mao@mongodb.com>2018-07-10 16:36:32 -0400
committerCheahuychou Mao <cheahuychou.mao@mongodb.com>2018-07-19 13:09:42 -0400
commita8e4cedfc7d7f48ac59fc4860ca6d8519421fdf5 (patch)
tree3127525a1a55bce311afb461f02ee8d73cc37f8e
parent6403c6a71e03cee4f6bebbc67b06ba46fbf632c4 (diff)
downloadmongo-a8e4cedfc7d7f48ac59fc4860ca6d8519421fdf5.tar.gz
SERVER-35849 Remove dependency of the write commands on sharding_runtime_d
-rw-r--r--src/mongo/db/ops/SConscript2
-rw-r--r--src/mongo/db/ops/write_ops_exec.cpp21
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/operation_sharding_state.cpp18
-rw-r--r--src/mongo/db/s/operation_sharding_state.h21
-rw-r--r--src/mongo/db/s/scoped_operation_completion_sharding_actions.cpp89
-rw-r--r--src/mongo/db/s/scoped_operation_completion_sharding_actions.h53
-rw-r--r--src/mongo/db/service_entry_point_common.cpp3
8 files changed, 194 insertions, 14 deletions
diff --git a/src/mongo/db/ops/SConscript b/src/mongo/db/ops/SConscript
index c272c6d3a2a..b7428b32608 100644
--- a/src/mongo/db/ops/SConscript
+++ b/src/mongo/db/ops/SConscript
@@ -12,10 +12,10 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/catalog_raii',
+ '$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/db/curop',
'$BUILD_DIR/mongo/db/repl/oplog',
'$BUILD_DIR/mongo/db/repl/repl_coordinator_interface',
- '$BUILD_DIR/mongo/db/s/sharding_runtime_d',
'$BUILD_DIR/mongo/db/stats/counters',
'$BUILD_DIR/mongo/db/write_ops',
'$BUILD_DIR/mongo/util/fail_point',
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp
index 1c6f944d75b..53b3404bdf4 100644
--- a/src/mongo/db/ops/write_ops_exec.cpp
+++ b/src/mongo/db/ops/write_ops_exec.cpp
@@ -36,6 +36,7 @@
#include "mongo/db/audit.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/collection.h"
+#include "mongo/db/catalog/collection_options.h"
#include "mongo/db/catalog/database_holder.h"
#include "mongo/db/catalog/document_validation.h"
#include "mongo/db/catalog_raii.h"
@@ -63,8 +64,7 @@
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/retryable_writes_stats.h"
#include "mongo/db/s/collection_sharding_state.h"
-#include "mongo/db/s/implicit_create_collection.h"
-#include "mongo/db/s/shard_filtering_metadata_refresh.h"
+#include "mongo/db/s/operation_sharding_state.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/db/session_catalog.h"
#include "mongo/db/stats/counters.h"
@@ -233,24 +233,19 @@ bool handleError(OperationContext* opCtx,
throw;
}
- if (auto staleInfo = ex.extraInfo<StaleConfigInfo>()) {
+ if (ex.extraInfo<StaleConfigInfo>()) {
if (!opCtx->getClient()->isInDirectClient()) {
- // We already have the StaleConfig exception, so just swallow any errors due to refresh
- onShardVersionMismatch(opCtx, nss, staleInfo->getVersionReceived()).ignore();
+ auto& oss = OperationShardingState::get(opCtx);
+ oss.setShardingOperationFailedStatus(ex.toStatus());
}
// Don't try doing more ops since they will fail with the same error.
// Command reply serializer will handle repeating this error if needed.
out->results.emplace_back(ex.toStatus());
return false;
- } else if (auto cannotImplicitCreateCollInfo =
- ex.extraInfo<CannotImplicitlyCreateCollectionInfo>()) {
- if (ShardingState::get(opCtx)->enabled()) {
- // Ignore status since we already put the cannot implicitly create error as the
- // result of the write.
- onCannotImplicitlyCreateCollection(opCtx, cannotImplicitCreateCollInfo->getNss())
- .ignore();
- }
+ } else if (ex.extraInfo<CannotImplicitlyCreateCollectionInfo>()) {
+ auto& oss = OperationShardingState::get(opCtx);
+ oss.setShardingOperationFailedStatus(ex.toStatus());
// Don't try doing more ops since they will fail with the same error.
// Command reply serializer will handle repeating this error if needed.
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript
index 782da1b15ad..8078dfc0c1c 100644
--- a/src/mongo/db/s/SConscript
+++ b/src/mongo/db/s/SConscript
@@ -42,6 +42,7 @@ env.Library(
'move_timing_helper.cpp',
'namespace_metadata_change_notifications.cpp',
'read_only_catalog_cache_loader.cpp',
+ 'scoped_operation_completion_sharding_actions.cpp',
'session_catalog_migration_destination.cpp',
'session_catalog_migration_source.cpp',
'shard_filtering_metadata_refresh.cpp',
diff --git a/src/mongo/db/s/operation_sharding_state.cpp b/src/mongo/db/s/operation_sharding_state.cpp
index 5527d066453..b4cc2457622 100644
--- a/src/mongo/db/s/operation_sharding_state.cpp
+++ b/src/mongo/db/s/operation_sharding_state.cpp
@@ -51,6 +51,10 @@ constexpr auto kDbVersionField = "databaseVersion"_sd;
OperationShardingState::OperationShardingState() = default;
+OperationShardingState::~OperationShardingState() {
+ invariant(!_shardingOperationFailedStatus);
+}
+
OperationShardingState& OperationShardingState::get(OperationContext* opCtx) {
return shardingMetadataDecoration(opCtx);
}
@@ -180,4 +184,18 @@ void OperationShardingState::setMovePrimaryCriticalSectionSignal(
_movePrimaryCriticalSectionSignal = std::move(critSecSignal);
}
+void OperationShardingState::setShardingOperationFailedStatus(const Status& status) {
+ invariant(!_shardingOperationFailedStatus);
+ _shardingOperationFailedStatus = std::move(status);
+}
+
+boost::optional<Status> OperationShardingState::resetShardingOperationFailedStatus() {
+ if (!_shardingOperationFailedStatus) {
+ return boost::none;
+ }
+ Status failedStatus = Status(*_shardingOperationFailedStatus);
+ _shardingOperationFailedStatus = boost::none;
+ return failedStatus;
+}
+
} // namespace mongo
diff --git a/src/mongo/db/s/operation_sharding_state.h b/src/mongo/db/s/operation_sharding_state.h
index e7133d04f98..e86f3d25e9d 100644
--- a/src/mongo/db/s/operation_sharding_state.h
+++ b/src/mongo/db/s/operation_sharding_state.h
@@ -54,6 +54,7 @@ class OperationShardingState {
public:
OperationShardingState();
+ ~OperationShardingState();
/**
* Retrieves a reference to the shard version decorating the OperationContext, 'opCtx'.
@@ -154,6 +155,22 @@ public:
*/
void setMovePrimaryCriticalSectionSignal(std::shared_ptr<Notification<void>> critSecSignal);
+ /**
+ * Stores the failed status in _shardingOperationFailedStatus.
+ *
+ * This method may only be called once when a rerouting exception occurs. The caller
+ * must process the status at exit.
+ */
+ void setShardingOperationFailedStatus(const Status& status);
+
+ /**
+ * Returns the failed status stored in _shardingOperationFailedStatus if any, and reset the
+ * status to none.
+ *
+ * This method may only be called when the caller wants to process the status.
+ */
+ boost::optional<Status> resetShardingOperationFailedStatus();
+
private:
// Specifies whether the request is allowed to create database/collection implicitly
bool _allowImplicitCollectionCreation{true};
@@ -175,6 +192,10 @@ private:
// to stale version and there was a movePrimary for that namespace, which was in critical
// section.
std::shared_ptr<Notification<void>> _movePrimaryCriticalSectionSignal;
+
+ // This value can only be set when a rerouting exception occurs during a write operation, and
+ // must be handled before this object gets destructed.
+ boost::optional<Status> _shardingOperationFailedStatus;
};
} // namespace mongo
diff --git a/src/mongo/db/s/scoped_operation_completion_sharding_actions.cpp b/src/mongo/db/s/scoped_operation_completion_sharding_actions.cpp
new file mode 100644
index 00000000000..dfc82d46894
--- /dev/null
+++ b/src/mongo/db/s/scoped_operation_completion_sharding_actions.cpp
@@ -0,0 +1,89 @@
+/*
+* Copyright (C) 2015 MongoDB Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* 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
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* 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 GNU Affero General 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_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/s/scoped_operation_completion_sharding_actions.h"
+
+#include "mongo/db/curop.h"
+#include "mongo/db/s/implicit_create_collection.h"
+#include "mongo/db/s/operation_sharding_state.h"
+#include "mongo/db/s/shard_filtering_metadata_refresh.h"
+#include "mongo/s/cannot_implicitly_create_collection_info.h"
+#include "mongo/s/stale_exception.h"
+#include "mongo/util/log.h"
+
+namespace mongo {
+
+namespace {
+
+const auto shardingOperationCompletionActionsRegistered =
+ OperationContext::declareDecoration<bool>();
+
+} // namespace
+
+ScopedOperationCompletionShardingActions::ScopedOperationCompletionShardingActions(
+ OperationContext* opCtx)
+ : _opCtx(opCtx) {
+ if (!opCtx->getClient()->isInDirectClient()) {
+ invariant(!shardingOperationCompletionActionsRegistered(_opCtx));
+ shardingOperationCompletionActionsRegistered(_opCtx) = true;
+ }
+}
+
+ScopedOperationCompletionShardingActions::~ScopedOperationCompletionShardingActions() noexcept {
+ if (_opCtx->getClient()->isInDirectClient())
+ return;
+
+ shardingOperationCompletionActionsRegistered(_opCtx) = false;
+
+ auto& oss = OperationShardingState::get(_opCtx);
+ auto status = oss.resetShardingOperationFailedStatus();
+ if (!status) {
+ return;
+ }
+
+ if (auto staleInfo = status->extraInfo<StaleConfigInfo>()) {
+ auto handleMismatchStatus =
+ onShardVersionMismatch(_opCtx, staleInfo->getNss(), staleInfo->getVersionReceived());
+ if (!handleMismatchStatus.isOK())
+ log() << "Failed to handle stale version exception"
+ << causedBy(redact(handleMismatchStatus));
+ } else if (auto cannotImplicitCreateCollInfo =
+ status->extraInfo<CannotImplicitlyCreateCollectionInfo>()) {
+ auto handleCannotImplicitCreateStatus =
+ onCannotImplicitlyCreateCollection(_opCtx, cannotImplicitCreateCollInfo->getNss());
+ if (!handleCannotImplicitCreateStatus.isOK())
+ log() << "Failed to handle CannotImplicitlyCreateCollection exception"
+ << causedBy(redact(handleCannotImplicitCreateStatus));
+ }
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/s/scoped_operation_completion_sharding_actions.h b/src/mongo/db/s/scoped_operation_completion_sharding_actions.h
new file mode 100644
index 00000000000..5d861520454
--- /dev/null
+++ b/src/mongo/db/s/scoped_operation_completion_sharding_actions.h
@@ -0,0 +1,53 @@
+/*
+* Copyright (C) 2015 MongoDB Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* 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
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* 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 GNU Affero General 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.
+*/
+
+#pragma once
+
+#include "mongo/base/disallow_copying.h"
+
+namespace mongo {
+
+/*
+ * This class has a destructor that handles rerouting exceptions that might have occurred
+ * during an operation. For this reason, there should be only one instance of this object
+ * on the chain of one OperationContext.
+*/
+class OperationContext;
+
+class ScopedOperationCompletionShardingActions {
+ MONGO_DISALLOW_COPYING(ScopedOperationCompletionShardingActions);
+
+public:
+ ScopedOperationCompletionShardingActions(OperationContext* opCtx);
+ ~ScopedOperationCompletionShardingActions() noexcept;
+
+private:
+ OperationContext* _opCtx;
+};
+
+} // namespace mongo
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index a655d6915ce..b87188cbc8a 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -65,6 +65,7 @@
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/s/implicit_create_collection.h"
#include "mongo/db/s/operation_sharding_state.h"
+#include "mongo/db/s/scoped_operation_completion_sharding_actions.h"
#include "mongo/db/s/shard_filtering_metadata_refresh.h"
#include "mongo/db/s/sharded_connection_info.h"
#include "mongo/db/s/sharding_state.h"
@@ -627,6 +628,7 @@ void execCommandDatabase(OperationContext* opCtx,
auto startOperationTime = getClientOperationTime(opCtx);
auto invocation = command->parse(opCtx, request);
boost::optional<OperationSessionInfoFromClient> sessionOptions = boost::none;
+
try {
{
stdx::lock_guard<Client> lk(*opCtx->getClient());
@@ -858,6 +860,7 @@ void execCommandDatabase(OperationContext* opCtx,
}
oss.setAllowImplicitCollectionCreation(allowImplicitCollectionCreationField);
+ ScopedOperationCompletionShardingActions operationCompletionShardingActions(opCtx);
// Can throw
opCtx->checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.