summaryrefslogtreecommitdiff
path: root/src/mongo/s
diff options
context:
space:
mode:
authorjannaerin <golden.janna@gmail.com>2018-04-03 13:30:30 -0400
committerjannaerin <golden.janna@gmail.com>2018-04-05 20:29:05 -0400
commit7a48a263485a585dac1e1289c830eafd35a3d54b (patch)
tree38544c586218bfa72bf7fd842c3ed6019e788ae3 /src/mongo/s
parent265a38952f11a5d9a6144a22f10dc59b138e0b69 (diff)
downloadmongo-7a48a263485a585dac1e1289c830eafd35a3d54b.tar.gz
SERVER-34145 Persist database version on shard
Diffstat (limited to 'src/mongo/s')
-rw-r--r--src/mongo/s/SConscript1
-rw-r--r--src/mongo/s/catalog/type_shard_database.cpp132
-rw-r--r--src/mongo/s/catalog/type_shard_database.h121
-rw-r--r--src/mongo/s/config_server_catalog_cache_loader.cpp16
4 files changed, 266 insertions, 4 deletions
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 57e488774b3..b815dc7b38e 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -116,6 +116,7 @@ env.Library(
'catalog/type_mongos.cpp',
'catalog/type_shard.cpp',
'catalog/type_shard_collection.cpp',
+ 'catalog/type_shard_database.cpp',
'catalog/type_tags.cpp',
'chunk_version.cpp',
'request_types/add_shard_request_type.cpp',
diff --git a/src/mongo/s/catalog/type_shard_database.cpp b/src/mongo/s/catalog/type_shard_database.cpp
new file mode 100644
index 00000000000..5be668cceae
--- /dev/null
+++ b/src/mongo/s/catalog/type_shard_database.cpp
@@ -0,0 +1,132 @@
+/**
+ * Copyright (C) 2018 10gen 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.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/s/catalog/type_shard_database.h"
+
+#include "mongo/base/status_with.h"
+#include "mongo/bson/bsonobj.h"
+#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/bson/util/bson_extract.h"
+#include "mongo/s/catalog/type_database.h"
+#include "mongo/util/assert_util.h"
+
+namespace mongo {
+
+using std::string;
+
+const NamespaceString ShardDatabaseType::ConfigNS(
+ NamespaceString::kShardConfigDatabasesCollectionName);
+
+const BSONField<std::string> ShardDatabaseType::name("_id");
+const BSONField<DatabaseVersion> ShardDatabaseType::version("version");
+const BSONField<std::string> ShardDatabaseType::primary("primary");
+const BSONField<bool> ShardDatabaseType::partitioned("partitioned");
+const BSONField<int> ShardDatabaseType::enterCriticalSectionCounter("enterCriticalSectionCounter");
+
+ShardDatabaseType::ShardDatabaseType(const std::string dbName,
+ boost::optional<DatabaseVersion> version,
+ const ShardId primary,
+ bool partitioned)
+ : _name(dbName), _version(version), _primary(primary), _partitioned(partitioned) {}
+
+StatusWith<ShardDatabaseType> ShardDatabaseType::fromBSON(const BSONObj& source) {
+ std::string dbName;
+ {
+ Status status = bsonExtractStringField(source, name.name(), &dbName);
+ if (!status.isOK())
+ return status;
+ }
+
+ boost::optional<DatabaseVersion> dbVersion = boost::none;
+ {
+ BSONObj versionField = source.getObjectField("version");
+ // TODO: Parse this unconditionally once featureCompatibilityVersion 3.6 is no longer
+ // supported.
+ if (!versionField.isEmpty()) {
+ dbVersion = DatabaseVersion::parse(IDLParserErrorContext("DatabaseType"), versionField);
+ }
+ }
+
+ std::string dbPrimary;
+ {
+ Status status = bsonExtractStringField(source, primary.name(), &dbPrimary);
+ if (!status.isOK())
+ return status;
+ }
+
+ bool dbPartitioned;
+ {
+ Status status =
+ bsonExtractBooleanFieldWithDefault(source, partitioned.name(), false, &dbPartitioned);
+ if (!status.isOK())
+ return status;
+ }
+
+ ShardDatabaseType shardDatabaseType(dbName, dbVersion, dbPrimary, dbPartitioned);
+
+ return shardDatabaseType;
+}
+
+BSONObj ShardDatabaseType::toBSON() const {
+ BSONObjBuilder builder;
+
+ builder.append(name.name(), _name);
+ if (_version) {
+ builder.append(version.name(), _version->toBSON());
+ }
+ builder.append(primary.name(), _primary.toString());
+ builder.append(partitioned.name(), _partitioned);
+
+ return builder.obj();
+}
+
+std::string ShardDatabaseType::toString() const {
+ return toBSON().toString();
+}
+
+void ShardDatabaseType::setDbVersion(boost::optional<DatabaseVersion> version) {
+ _version = version;
+}
+
+void ShardDatabaseType::setDbName(const std::string& dbName) {
+ invariant(!dbName.empty());
+ _name = dbName;
+}
+
+void ShardDatabaseType::setPrimary(const ShardId& primary) {
+ invariant(primary.isValid());
+ _primary = primary;
+}
+
+void ShardDatabaseType::setPartitioned(bool partitioned) {
+ _partitioned = partitioned;
+}
+
+} // namespace mongo
diff --git a/src/mongo/s/catalog/type_shard_database.h b/src/mongo/s/catalog/type_shard_database.h
new file mode 100644
index 00000000000..f8b0209636d
--- /dev/null
+++ b/src/mongo/s/catalog/type_shard_database.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (C) 2018 10gen 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 <boost/optional.hpp>
+#include <string>
+
+#include "mongo/db/jsobj.h"
+#include "mongo/s/database_version_gen.h"
+#include "mongo/s/shard_id.h"
+
+namespace mongo {
+
+class Status;
+template <typename T>
+class StatusWith;
+
+/**
+ * This class represents the layout and contents of documents contained in the shard server's
+ * config.databases collection. All manipulation of documents coming from that collection should
+ * be done with this class.
+ *
+ * Expected shard server config.databases collection format:
+ * {
+ * "_id" : "foo",
+ * "version" : {
+ * "uuid" : UUID
+ * "lastMod" : 1
+ * },
+ * "primary": "shard0000",
+ * "partitioned": true,
+ * "enterCriticalSectionCounter" : 4 // optional
+ * }
+ *
+ * enterCriticalSectionCounter is currently just an OpObserver signal, thus otherwise ignored here.
+ */
+class ShardDatabaseType {
+public:
+ // Name of the database collection on the shard server.
+ static const NamespaceString ConfigNS;
+
+ static const BSONField<std::string> name; // "_id"
+ static const BSONField<DatabaseVersion> version;
+ static const BSONField<std::string> primary;
+ static const BSONField<bool> partitioned;
+ static const BSONField<int> enterCriticalSectionCounter;
+
+ ShardDatabaseType(const std::string dbName,
+ boost::optional<DatabaseVersion> version,
+ const ShardId primary,
+ bool partitioned);
+
+ /**
+ * Constructs a new ShardDatabaseType object from BSON. Also does validation of the contents.
+ */
+ static StatusWith<ShardDatabaseType> fromBSON(const BSONObj& source);
+
+ /**
+ * Returns the BSON representation of this shard database type object.
+ */
+ BSONObj toBSON() const;
+
+ /**
+ * Returns a std::string representation of the current internal state.
+ */
+ std::string toString() const;
+
+ const std::string& getDbName() const {
+ return _name;
+ }
+ void setDbName(const std::string& dbName);
+
+ const boost::optional<DatabaseVersion> getDbVersion() const {
+ return _version;
+ }
+ void setDbVersion(boost::optional<DatabaseVersion> version);
+
+ const ShardId& getPrimary() const {
+ return _primary;
+ }
+ void setPrimary(const ShardId& primary);
+
+ bool getPartitioned() const {
+ return _partitioned;
+ }
+ void setPartitioned(bool partitioned);
+
+private:
+ std::string _name;
+ boost::optional<DatabaseVersion> _version;
+ ShardId _primary;
+ bool _partitioned;
+};
+
+} // namespace mongo
diff --git a/src/mongo/s/config_server_catalog_cache_loader.cpp b/src/mongo/s/config_server_catalog_cache_loader.cpp
index 68a6817ec83..eaa2669b072 100644
--- a/src/mongo/s/config_server_catalog_cache_loader.cpp
+++ b/src/mongo/s/config_server_catalog_cache_loader.cpp
@@ -200,13 +200,21 @@ void ConfigServerCatalogCacheLoader::getDatabase(
stdx::function<void(OperationContext*, StatusWith<DatabaseType>)> callbackFn) {
if (MONGO_FAIL_POINT(callShardServerCallbackFn)) {
- uassertStatusOK(_threadPool.schedule([ dbName, callbackFn ]() noexcept {
+ uassertStatusOK(_threadPool.schedule([ name = dbName.toString(), callbackFn ]() noexcept {
auto opCtx = Client::getCurrent()->makeOperationContext();
- const auto dbVersion = Versioning::newDatabaseVersion();
- DatabaseType dbt(dbName.toString(), ShardId("PrimaryShard"), false, dbVersion);
+ auto swDbt = [&]() -> StatusWith<DatabaseType> {
+ try {
- callbackFn(opCtx.get(), dbt);
+ const auto dbVersion = Versioning::newDatabaseVersion();
+ DatabaseType dbt(std::move(name), ShardId("PrimaryShard"), false, dbVersion);
+ return dbt;
+ } catch (const DBException& ex) {
+ return ex.toStatus();
+ }
+ }();
+
+ callbackFn(opCtx.get(), swDbt);
}));
}
}