diff options
author | Cheahuychou Mao <cheahuychou.mao@mongodb.com> | 2018-07-10 16:36:32 -0400 |
---|---|---|
committer | Cheahuychou Mao <cheahuychou.mao@mongodb.com> | 2018-07-19 13:09:42 -0400 |
commit | a8e4cedfc7d7f48ac59fc4860ca6d8519421fdf5 (patch) | |
tree | 3127525a1a55bce311afb461f02ee8d73cc37f8e | |
parent | 6403c6a71e03cee4f6bebbc67b06ba46fbf632c4 (diff) | |
download | mongo-a8e4cedfc7d7f48ac59fc4860ca6d8519421fdf5.tar.gz |
SERVER-35849 Remove dependency of the write commands on sharding_runtime_d
-rw-r--r-- | src/mongo/db/ops/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 21 | ||||
-rw-r--r-- | src/mongo/db/s/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/s/operation_sharding_state.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/s/operation_sharding_state.h | 21 | ||||
-rw-r--r-- | src/mongo/db/s/scoped_operation_completion_sharding_actions.cpp | 89 | ||||
-rw-r--r-- | src/mongo/db/s/scoped_operation_completion_sharding_actions.h | 53 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 3 |
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. |