summaryrefslogtreecommitdiff
path: root/src/mongo/s
diff options
context:
space:
mode:
authorjannaerin <golden.janna@gmail.com>2019-02-22 17:32:05 -0500
committerjannaerin <golden.janna@gmail.com>2019-02-27 15:30:51 -0500
commit4b114240edbfe4446f9f4de25c10bd67350b0f40 (patch)
tree72a144b6a7eeab39de2675ffe48922dfa6608e78 /src/mongo/s
parent2ecd83f822b242db1c13f2abc3ff3593ba622149 (diff)
downloadmongo-4b114240edbfe4446f9f4de25c10bd67350b0f40.tar.gz
SERVER-39778 Create WouldChangeOwningShard exception
Diffstat (limited to 'src/mongo/s')
-rw-r--r--src/mongo/s/SConscript1
-rw-r--r--src/mongo/s/would_change_owning_shard_exception.cpp71
-rw-r--r--src/mongo/s/would_change_owning_shard_exception.h98
3 files changed, 170 insertions, 0 deletions
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index d52fc8cb99f..eb8b05a073d 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -163,6 +163,7 @@ env.Library(
'database_version_helpers.cpp',
'shard_id.cpp',
'stale_exception.cpp',
+ 'would_change_owning_shard_exception.cpp',
env.Idlc('catalog/type_chunk_base.idl')[0],
env.Idlc('database_version.idl')[0],
env.Idlc('request_types/clone_catalog_data.idl')[0],
diff --git a/src/mongo/s/would_change_owning_shard_exception.cpp b/src/mongo/s/would_change_owning_shard_exception.cpp
new file mode 100644
index 00000000000..9c257f9388e
--- /dev/null
+++ b/src/mongo/s/would_change_owning_shard_exception.cpp
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2019-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/s/would_change_owning_shard_exception.h"
+
+#include "mongo/base/init.h"
+#include "mongo/util/assert_util.h"
+
+namespace mongo {
+namespace {
+
+MONGO_INIT_REGISTER_ERROR_EXTRA_INFO(WouldChangeOwningShardInfo);
+constexpr StringData kOriginalQueryPredicate = "originalQueryPredicate"_sd;
+constexpr StringData kOriginalUpdate = "originalUpdate"_sd;
+constexpr StringData kPostImage = "postImage"_sd;
+
+} // namespace
+
+void WouldChangeOwningShardInfo::serialize(BSONObjBuilder* bob) const {
+ bob->append(kOriginalQueryPredicate, _originalQueryPredicate);
+ if (_originalUpdate)
+ bob->append(kOriginalUpdate, _originalUpdate.get());
+ if (_postImage)
+ bob->append(kPostImage, _postImage.get());
+}
+
+std::shared_ptr<const ErrorExtraInfo> WouldChangeOwningShardInfo::parse(const BSONObj& obj) {
+ return std::make_shared<WouldChangeOwningShardInfo>(parseFromCommandError(obj));
+}
+
+WouldChangeOwningShardInfo WouldChangeOwningShardInfo::parseFromCommandError(const BSONObj& obj) {
+ boost::optional<BSONObj> originalUpdate = boost::none;
+ boost::optional<BSONObj> postImage = boost::none;
+ if (obj[kOriginalUpdate])
+ originalUpdate = obj[kOriginalUpdate].Obj().getOwned();
+ if (obj[kPostImage])
+ postImage = obj[kPostImage].Obj().getOwned();
+
+ return WouldChangeOwningShardInfo(
+ obj[kOriginalQueryPredicate].Obj().getOwned(), originalUpdate, postImage);
+}
+
+} // namespace mongo
diff --git a/src/mongo/s/would_change_owning_shard_exception.h b/src/mongo/s/would_change_owning_shard_exception.h
new file mode 100644
index 00000000000..ad5f36081b6
--- /dev/null
+++ b/src/mongo/s/would_change_owning_shard_exception.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2019-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.
+ */
+
+#pragma once
+
+#include "mongo/base/error_extra_info.h"
+#include "mongo/bson/bsonobj.h"
+#include "mongo/bson/bsonobjbuilder.h"
+
+namespace mongo {
+
+/**
+ * This error is thrown when an update would cause a document to be owned by a different
+ * shard. If the update is part of a multi statement transaction, we will attach the
+ * query from the original update and the post image returned by the update stage. MongoS
+ * will use these to delete the original doc and insert the new doc. If the update is a
+ * retryable write, we will attach both the query and the update fields from the original
+ * update command. MongoS will use these to start an internal transaction and re-run the
+ * update command.
+ */
+class WouldChangeOwningShardInfo final : public ErrorExtraInfo {
+public:
+ static constexpr auto code = ErrorCodes::WouldChangeOwningShard;
+
+ explicit WouldChangeOwningShardInfo(const BSONObj& originalQueryPredicate,
+ const boost::optional<BSONObj>& originalUpdate,
+ const boost::optional<BSONObj>& postImage)
+ : _originalQueryPredicate(originalQueryPredicate.getOwned()) {
+ invariant(!(originalUpdate && postImage));
+ invariant(originalUpdate || postImage);
+
+ if (originalUpdate)
+ _originalUpdate = originalUpdate->getOwned();
+ if (postImage)
+ _postImage = postImage->getOwned();
+ }
+
+ const auto& getOriginalQueryPredicate() const {
+ return _originalQueryPredicate;
+ }
+
+ const auto& getOriginalUpdate() const {
+ return _originalUpdate;
+ }
+
+ const auto& getPostImage() const {
+ return _postImage;
+ }
+
+ BSONObj toBSON() const {
+ BSONObjBuilder bob;
+ serialize(&bob);
+ return bob.obj();
+ }
+
+ void serialize(BSONObjBuilder* bob) const override;
+ static std::shared_ptr<const ErrorExtraInfo> parse(const BSONObj&);
+ static WouldChangeOwningShardInfo parseFromCommandError(const BSONObj& commandError);
+
+private:
+ // the 'q' portion of the original update comamand
+ BSONObj _originalQueryPredicate;
+
+ // The 'u' portion of the original update command
+ boost::optional<BSONObj> _originalUpdate;
+
+ // The post image returned by the update stage
+ boost::optional<BSONObj> _postImage;
+};
+using WouldChangeOwningShardException = ExceptionFor<ErrorCodes::WouldChangeOwningShard>;
+
+} // namespace mongo