summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-04-15 18:41:32 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-04-20 16:31:12 -0400
commit0e45dbdbfda0ff381308b37d75235cad1da3db54 (patch)
tree5917a27620cc0c034a5e20d609917ce7660ebe21
parentf3c0c1cc6957efb0c48b1b757c3de2f20749db02 (diff)
downloadmongo-0e45dbdbfda0ff381308b37d75235cad1da3db54.tar.gz
SERVER-23696 Get rid of SettingsType
Splits all the functionality of SettingsType into the constituent ChunkSizeSettings and BalancerSettings and moves it under the BalancerConfiguration utility.
-rw-r--r--src/mongo/db/s/sharding_state_test.cpp2
-rw-r--r--src/mongo/s/SConscript2
-rw-r--r--src/mongo/s/balancer/balancer_configuration.cpp280
-rw-r--r--src/mongo/s/balancer/balancer_configuration.h147
-rw-r--r--src/mongo/s/balancer/balancer_configuration_test.cpp263
-rw-r--r--src/mongo/s/catalog/SConscript2
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp2
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp97
-rw-r--r--src/mongo/s/catalog/type_settings.cpp269
-rw-r--r--src/mongo/s/catalog/type_settings.h192
-rw-r--r--src/mongo/s/catalog/type_settings_test.cpp191
-rw-r--r--src/mongo/s/mongos_options.cpp2
-rw-r--r--src/mongo/s/mongos_options.h2
-rw-r--r--src/mongo/s/sharding_initialization.cpp2
-rw-r--r--src/mongo/s/sharding_test_fixture.cpp2
15 files changed, 581 insertions, 874 deletions
diff --git a/src/mongo/db/s/sharding_state_test.cpp b/src/mongo/db/s/sharding_state_test.cpp
index 3fb118ec87e..664f3961211 100644
--- a/src/mongo/db/s/sharding_state_test.cpp
+++ b/src/mongo/db/s/sharding_state_test.cpp
@@ -83,7 +83,7 @@ void initGrid(OperationContext* txn, const ConnectionString& configConnString) {
stdx::make_unique<CatalogCache>(),
std::move(shardRegistry),
stdx::make_unique<ClusterCursorManager>(txn->getServiceContext()->getPreciseClockSource()),
- stdx::make_unique<BalancerConfiguration>(BalancerConfiguration::kDefaultMaxChunkSizeBytes),
+ stdx::make_unique<BalancerConfiguration>(ChunkSizeSettingsType::kDefaultMaxChunkSizeBytes),
std::move(executorPool),
mockNetwork);
}
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 02f45fd0876..9c5b15b7daf 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -230,12 +230,14 @@ env.CppUnitTest(
target='mongoscore_test',
source=[
'balancer_policy_tests.cpp',
+ 'balancer/balancer_configuration_test.cpp',
'balancer/cluster_statistics_test.cpp',
'shard_key_pattern_test.cpp',
],
LIBDEPS=[
'coreshard',
'mongoscore',
+ 'sharding_test_fixture',
'$BUILD_DIR/mongo/db/auth/authorization_manager_mock_init',
'$BUILD_DIR/mongo/db/service_context_noop_init',
]
diff --git a/src/mongo/s/balancer/balancer_configuration.cpp b/src/mongo/s/balancer/balancer_configuration.cpp
index b40aa1e8c32..8c96ffa03f8 100644
--- a/src/mongo/s/balancer/balancer_configuration.cpp
+++ b/src/mongo/s/balancer/balancer_configuration.cpp
@@ -33,48 +33,56 @@
#include "mongo/s/balancer/balancer_configuration.h"
#include "mongo/base/status.h"
+#include "mongo/base/status_with.h"
+#include "mongo/bson/bsonobj.h"
+#include "mongo/bson/util/bson_extract.h"
#include "mongo/s/catalog/catalog_manager.h"
#include "mongo/s/grid.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
namespace mongo {
+namespace {
-const uint64_t BalancerConfiguration::kDefaultMaxChunkSizeBytes{64 * 1024 * 1024};
+const char kValue[] = "value";
+const char kStopped[] = "stopped";
+const char kActiveWindow[] = "activeWindow";
+const char kWaitForDelete[] = "_waitForDelete";
+
+} // namespace
+
+const char BalancerSettingsType::kKey[] = "balancer";
+
+const char ChunkSizeSettingsType::kKey[] = "chunksize";
+const uint64_t ChunkSizeSettingsType::kDefaultMaxChunkSizeBytes{64 * 1024 * 1024};
BalancerConfiguration::BalancerConfiguration(uint64_t defaultMaxChunkSizeBytes)
- : _secondaryThrottle(
- MigrationSecondaryThrottleOptions::create(MigrationSecondaryThrottleOptions::kDefault)),
+ : _balancerSettings(BalancerSettingsType::createDefault()),
_defaultMaxChunkSizeBytes(defaultMaxChunkSizeBytes) {
- invariant(checkMaxChunkSizeValid(defaultMaxChunkSizeBytes));
-
- _useDefaultBalancerSettings();
- _useDefaultChunkSizeSettings();
+ // The default must always be created with the max chunk size value prevalidated
+ invariant(ChunkSizeSettingsType::checkMaxChunkSizeValid(_defaultMaxChunkSizeBytes));
+ _maxChunkSizeBytes.store(_defaultMaxChunkSizeBytes);
}
BalancerConfiguration::~BalancerConfiguration() = default;
bool BalancerConfiguration::isBalancerActive() const {
- if (!_shouldBalance.loadRelaxed()) {
- return false;
- }
-
stdx::lock_guard<stdx::mutex> lk(_balancerSettingsMutex);
- if (_balancerSettings.isBalancerActiveWindowSet()) {
- return _balancerSettings.inBalancingWindow(boost::posix_time::second_clock::local_time());
+ if (!_balancerSettings.shouldBalance()) {
+ return false;
}
- return true;
+ return _balancerSettings.isTimeInBalancingWindow(boost::posix_time::second_clock::local_time());
}
MigrationSecondaryThrottleOptions BalancerConfiguration::getSecondaryThrottle() const {
stdx::lock_guard<stdx::mutex> lk(_balancerSettingsMutex);
- return _secondaryThrottle;
+ return _balancerSettings.getSecondaryThrottle();
}
bool BalancerConfiguration::waitForDelete() const {
stdx::lock_guard<stdx::mutex> lk(_balancerSettingsMutex);
- return _waitForDelete;
+ return _balancerSettings.waitForDelete();
}
Status BalancerConfiguration::refreshAndCheck(OperationContext* txn) {
@@ -97,105 +105,203 @@ Status BalancerConfiguration::refreshAndCheck(OperationContext* txn) {
return Status::OK();
}
-bool BalancerConfiguration::checkMaxChunkSizeValid(uint64_t maxChunkSize) {
- if (maxChunkSize >= (1024 * 1024) && maxChunkSize <= (1024 * 1024 * 1024)) {
- return true;
+Status BalancerConfiguration::_refreshBalancerSettings(OperationContext* txn) {
+ BalancerSettingsType settings = BalancerSettingsType::createDefault();
+
+ auto settingsObjStatus =
+ Grid::get(txn)->catalogManager(txn)->getGlobalSettings(txn, BalancerSettingsType::kKey);
+ if (settingsObjStatus.isOK()) {
+ auto settingsStatus = BalancerSettingsType::fromBSON(settingsObjStatus.getValue());
+ if (!settingsStatus.isOK()) {
+ return settingsStatus.getStatus();
+ }
+
+ settings = std::move(settingsStatus.getValue());
+ } else if (settingsObjStatus != ErrorCodes::NoMatchingDocument) {
+ return settingsObjStatus.getStatus();
}
- return false;
+ stdx::lock_guard<stdx::mutex> lk(_balancerSettingsMutex);
+ _balancerSettings = std::move(settings);
+
+ return Status::OK();
}
-Status BalancerConfiguration::_refreshBalancerSettings(OperationContext* txn) {
- SettingsType balancerSettings;
-
- auto balanceSettingsStatus =
- Grid::get(txn)->catalogManager(txn)->getGlobalSettings(txn, SettingsType::BalancerDocKey);
- if (balanceSettingsStatus.isOK()) {
- auto settingsTypeStatus =
- SettingsType::fromBSON(std::move(balanceSettingsStatus.getValue()));
- if (!settingsTypeStatus.isOK()) {
- return settingsTypeStatus.getStatus();
+Status BalancerConfiguration::_refreshChunkSizeSettings(OperationContext* txn) {
+ ChunkSizeSettingsType settings =
+ ChunkSizeSettingsType::createDefault(_defaultMaxChunkSizeBytes);
+
+ auto settingsObjStatus =
+ grid.catalogManager(txn)->getGlobalSettings(txn, ChunkSizeSettingsType::kKey);
+ if (settingsObjStatus.isOK()) {
+ auto settingsStatus = ChunkSizeSettingsType::fromBSON(settingsObjStatus.getValue());
+ if (!settingsStatus.isOK()) {
+ return settingsStatus.getStatus();
}
- balancerSettings = std::move(settingsTypeStatus.getValue());
- } else if (balanceSettingsStatus.getStatus() != ErrorCodes::NoMatchingDocument) {
- return balanceSettingsStatus.getStatus();
- } else {
- _useDefaultBalancerSettings();
- return Status::OK();
+
+ settings = std::move(settingsStatus.getValue());
+ } else if (settingsObjStatus != ErrorCodes::NoMatchingDocument) {
+ return settingsObjStatus.getStatus();
}
- if (balancerSettings.isBalancerStoppedSet() && balancerSettings.getBalancerStopped()) {
- _shouldBalance.store(false);
- } else {
- _shouldBalance.store(true);
+ if (settings.getMaxChunkSizeBytes() != getMaxChunkSizeBytes()) {
+ log() << "MaxChunkSize changing from " << getMaxChunkSizeBytes() / (1024 * 1024) << "MB"
+ << " to " << settings.getMaxChunkSizeBytes() / (1024 * 1024) << "MB";
+
+ _maxChunkSizeBytes.store(settings.getMaxChunkSizeBytes());
}
- stdx::lock_guard<stdx::mutex> lk(_balancerSettingsMutex);
- _balancerSettings = std::move(balancerSettings);
+ return Status::OK();
+}
- if (_balancerSettings.isKeySet()) {
- _secondaryThrottle =
- uassertStatusOK(MigrationSecondaryThrottleOptions::createFromBalancerConfig(
- _balancerSettings.toBSON()));
- } else {
- _secondaryThrottle =
- MigrationSecondaryThrottleOptions::create(MigrationSecondaryThrottleOptions::kDefault);
+BalancerSettingsType::BalancerSettingsType()
+ : _secondaryThrottle(
+ MigrationSecondaryThrottleOptions::create(MigrationSecondaryThrottleOptions::kDefault)) {}
+
+BalancerSettingsType BalancerSettingsType::createDefault() {
+ return BalancerSettingsType();
+}
+
+StatusWith<BalancerSettingsType> BalancerSettingsType::fromBSON(const BSONObj& obj) {
+ BalancerSettingsType settings;
+
+ {
+ bool stopped;
+ Status status = bsonExtractBooleanFieldWithDefault(obj, kStopped, false, &stopped);
+ if (!status.isOK())
+ return status;
+ settings._shouldBalance = !stopped;
}
- if (_balancerSettings.isWaitForDeleteSet() && _balancerSettings.getWaitForDelete()) {
- _waitForDelete = true;
- } else {
- _waitForDelete = false;
+ {
+ BSONElement activeWindowElem;
+ Status status = bsonExtractTypedField(obj, kActiveWindow, Object, &activeWindowElem);
+ if (status.isOK()) {
+ const BSONObj balancingWindowObj = activeWindowElem.Obj();
+ if (balancingWindowObj.isEmpty()) {
+ return Status(ErrorCodes::BadValue, "activeWindow not specified");
+ }
+
+ // Check if both 'start' and 'stop' are present
+ const std::string start = balancingWindowObj.getField("start").str();
+ const std::string stop = balancingWindowObj.getField("stop").str();
+
+ if (start.empty() || stop.empty()) {
+ return Status(ErrorCodes::BadValue,
+ str::stream()
+ << "must specify both start and stop of balancing window: "
+ << balancingWindowObj);
+ }
+
+ // Check that both 'start' and 'stop' are valid time-of-day
+ boost::posix_time::ptime startTime;
+ boost::posix_time::ptime stopTime;
+ if (!toPointInTime(start, &startTime) || !toPointInTime(stop, &stopTime)) {
+ return Status(ErrorCodes::BadValue,
+ str::stream() << kActiveWindow << " format is "
+ << " { start: \"hh:mm\" , stop: \"hh:mm\" }");
+ }
+
+ // Check that start and stop designate different time points
+ if (startTime == stopTime) {
+ return Status(ErrorCodes::BadValue,
+ str::stream() << "start and stop times must be different");
+ }
+
+ settings._activeWindowStart = startTime;
+ settings._activeWindowStop = stopTime;
+ } else if (status != ErrorCodes::NoSuchKey) {
+ return status;
+ }
}
- return Status::OK();
-}
+ {
+ auto secondaryThrottleStatus =
+ MigrationSecondaryThrottleOptions::createFromBalancerConfig(obj);
+ if (!secondaryThrottleStatus.isOK()) {
+ return secondaryThrottleStatus.getStatus();
+ }
+
+ settings._secondaryThrottle = std::move(secondaryThrottleStatus.getValue());
+ }
+
+ {
+ bool waitForDelete;
+ Status status =
+ bsonExtractBooleanFieldWithDefault(obj, kWaitForDelete, false, &waitForDelete);
+ if (!status.isOK())
+ return status;
+
+ settings._waitForDelete = waitForDelete;
+ }
-void BalancerConfiguration::_useDefaultBalancerSettings() {
- _shouldBalance.store(true);
- _balancerSettings = SettingsType{};
- _waitForDelete = false;
- _secondaryThrottle =
- MigrationSecondaryThrottleOptions::create(MigrationSecondaryThrottleOptions::kDefault);
+ return settings;
}
-Status BalancerConfiguration::_refreshChunkSizeSettings(OperationContext* txn) {
- SettingsType chunkSizeSettings;
-
- auto chunkSizeSettingsStatus =
- grid.catalogManager(txn)->getGlobalSettings(txn, SettingsType::ChunkSizeDocKey);
- if (chunkSizeSettingsStatus.isOK()) {
- auto settingsTypeStatus =
- SettingsType::fromBSON(std::move(chunkSizeSettingsStatus.getValue()));
- if (!settingsTypeStatus.isOK()) {
- return settingsTypeStatus.getStatus();
+bool BalancerSettingsType::isTimeInBalancingWindow(const boost::posix_time::ptime& now) const {
+ invariant(!_activeWindowStart == !_activeWindowStop);
+
+ if (!_activeWindowStart) {
+ return true;
+ }
+
+ LOG(1).stream() << "inBalancingWindow: "
+ << " now: " << now << " startTime: " << *_activeWindowStart
+ << " stopTime: " << *_activeWindowStop;
+
+ if (*_activeWindowStop > *_activeWindowStart) {
+ if ((now >= *_activeWindowStart) && (now <= *_activeWindowStop)) {
+ return true;
+ }
+ } else if (*_activeWindowStart > *_activeWindowStop) {
+ if ((now >= *_activeWindowStart) || (now <= *_activeWindowStop)) {
+ return true;
}
- chunkSizeSettings = std::move(settingsTypeStatus.getValue());
- } else if (chunkSizeSettingsStatus.getStatus() != ErrorCodes::NoMatchingDocument) {
- return chunkSizeSettingsStatus.getStatus();
} else {
- _useDefaultChunkSizeSettings();
- return Status::OK();
+ MONGO_UNREACHABLE;
}
- const uint64_t newMaxChunkSizeBytes = chunkSizeSettings.getChunkSizeMB() * 1024 * 1024;
+ return false;
+}
+
+ChunkSizeSettingsType::ChunkSizeSettingsType() = default;
+
+ChunkSizeSettingsType ChunkSizeSettingsType::createDefault(int maxChunkSizeBytes) {
+ // The default must always be created with the max chunk size value prevalidated
+ invariant(ChunkSizeSettingsType::checkMaxChunkSizeValid(maxChunkSizeBytes));
- if (!checkMaxChunkSizeValid(newMaxChunkSizeBytes)) {
+ ChunkSizeSettingsType settings;
+ settings._maxChunkSizeBytes = maxChunkSizeBytes;
+
+ return settings;
+}
+
+StatusWith<ChunkSizeSettingsType> ChunkSizeSettingsType::fromBSON(const BSONObj& obj) {
+ long long maxChunkSizeMB;
+ Status status = bsonExtractIntegerField(obj, kValue, &maxChunkSizeMB);
+ if (!status.isOK())
+ return status;
+
+ const uint64_t maxChunkSizeBytes = maxChunkSizeMB * 1024 * 1024;
+
+ if (!checkMaxChunkSizeValid(maxChunkSizeBytes)) {
return {ErrorCodes::BadValue,
- str::stream() << chunkSizeSettings.getChunkSizeMB()
- << " is not a valid value for MaxChunkSize"};
+ str::stream() << maxChunkSizeMB << " is not a valid value for " << kKey};
}
- if (newMaxChunkSizeBytes != getMaxChunkSizeBytes()) {
- log() << "MaxChunkSize changing from " << getMaxChunkSizeBytes() / (1024 * 1024) << "MB"
- << " to " << newMaxChunkSizeBytes / (1024 * 1024) << "MB";
- }
+ ChunkSizeSettingsType settings;
+ settings._maxChunkSizeBytes = maxChunkSizeBytes;
- return Status::OK();
+ return settings;
}
-void BalancerConfiguration::_useDefaultChunkSizeSettings() {
- _maxChunkSizeBytes.store(_defaultMaxChunkSizeBytes);
+bool ChunkSizeSettingsType::checkMaxChunkSizeValid(uint64_t maxChunkSizeBytes) {
+ if (maxChunkSizeBytes >= (1024 * 1024) && maxChunkSizeBytes <= (1024 * 1024 * 1024)) {
+ return true;
+ }
+
+ return false;
}
+
} // namespace mongo
diff --git a/src/mongo/s/balancer/balancer_configuration.h b/src/mongo/s/balancer/balancer_configuration.h
index fafc8a7bd1d..0cc2cb48cd4 100644
--- a/src/mongo/s/balancer/balancer_configuration.h
+++ b/src/mongo/s/balancer/balancer_configuration.h
@@ -28,34 +28,141 @@
#pragma once
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/optional.hpp>
#include <cstdint>
#include "mongo/base/disallow_copying.h"
-#include "mongo/s/catalog/type_settings.h"
#include "mongo/s/migration_secondary_throttle_options.h"
#include "mongo/stdx/mutex.h"
#include "mongo/platform/atomic_word.h"
namespace mongo {
+class BSONObj;
class MigrationSecondaryThrottleOptions;
class OperationContext;
class Status;
+template <typename T>
+class StatusWith;
/**
- * Contains settings, which control the behaviour of the balancer.
+ * Utility class to parse the balancer settings document, which has the following format:
+ *
+ * balancer: {
+ * stopped: <true|false>,
+ * activeWindow: { start: "<HH:MM>", stop: "<HH:MM>" }
+ * }
*/
-class BalancerConfiguration {
- MONGO_DISALLOW_COPYING(BalancerConfiguration);
+class BalancerSettingsType {
+public:
+ // The key under which this setting is stored on the config server
+ static const char kKey[];
+
+ /**
+ * Constructs a settings object with the default values. To be used when no balancer settings
+ * have been specified.
+ */
+ static BalancerSettingsType createDefault();
+
+ /**
+ * Interprets the BSON content as balancer settings and extracts the respective values.
+ */
+ static StatusWith<BalancerSettingsType> fromBSON(const BSONObj& obj);
+
+ /**
+ * Returns whether the balancer is enabled.
+ */
+ bool shouldBalance() const {
+ return _shouldBalance;
+ }
+
+ /**
+ * Returns true if either 'now' is in the balancing window or if no balancing window exists.
+ */
+ bool isTimeInBalancingWindow(const boost::posix_time::ptime& now) const;
+
+ /**
+ * Returns the secondary throttle options.
+ */
+ const MigrationSecondaryThrottleOptions& getSecondaryThrottle() const {
+ return _secondaryThrottle;
+ }
+
+ /**
+ * Returns whether the balancer should wait for deletions after each completed move.
+ */
+ bool waitForDelete() const {
+ return _waitForDelete;
+ }
+
+
+private:
+ BalancerSettingsType();
+
+ bool _shouldBalance{true};
+ boost::optional<boost::posix_time::ptime> _activeWindowStart;
+ boost::optional<boost::posix_time::ptime> _activeWindowStop;
+
+ MigrationSecondaryThrottleOptions _secondaryThrottle;
+
+ bool _waitForDelete{false};
+};
+
+/**
+ * Utility class to parse the chunk size settings document, which has the following format:
+ *
+ * chunksize: { value: <value in MB between 1 and 1024> }
+ */
+class ChunkSizeSettingsType {
public:
+ // The key under which this setting is stored on the config server
+ static const char kKey[];
+
// Default value used for the max chunk size if one is not specified in the balancer
// configuration
static const uint64_t kDefaultMaxChunkSizeBytes;
/**
- * Primes the balancer configuration with some default values. These settings may change at a
- * later time after a call to refresh().
+ * Constructs a settings object with the default values. To be used when no chunk size settings
+ * have been specified.
+ */
+ static ChunkSizeSettingsType createDefault(int maxChunkSizeBytes);
+
+ /**
+ * Interprets the BSON content as chunk size settings and extracts the respective values.
+ */
+ static StatusWith<ChunkSizeSettingsType> fromBSON(const BSONObj& obj);
+
+ uint64_t getMaxChunkSizeBytes() const {
+ return _maxChunkSizeBytes;
+ }
+
+ /**
+ * Validates that the specified max chunk size value (in bytes) is allowed.
+ */
+ static bool checkMaxChunkSizeValid(uint64_t maxChunkSizeBytes);
+
+private:
+ ChunkSizeSettingsType();
+
+ uint64_t _maxChunkSizeBytes{kDefaultMaxChunkSizeBytes};
+};
+
+/**
+ * Contains settings, which control the behaviour of the balancer.
+ */
+class BalancerConfiguration {
+ MONGO_DISALLOW_COPYING(BalancerConfiguration);
+
+public:
+ /**
+ * Primes the balancer configuration with some default values. The effective settings may change
+ * at a later time after a call to refresh().
+ *
+ * defaultMaxChunkSizeBytes indicates the value to be use for the MaxChunkSize parameter if one
+ * has not been specified in config.settings. This parameter must have been pre-validated.
*/
BalancerConfiguration(uint64_t defaultMaxChunkSizeBytes);
~BalancerConfiguration();
@@ -94,11 +201,6 @@ public:
*/
Status refreshAndCheck(OperationContext* txn);
- /**
- * Validates that the specified max chunk size value (in bytes) is allowed.
- */
- static bool checkMaxChunkSizeValid(uint64_t maxChunkSizeBytes);
-
private:
/**
* Reloads the balancer configuration from the settings document. Fails if the settings document
@@ -107,37 +209,22 @@ private:
Status _refreshBalancerSettings(OperationContext* txn);
/**
- * If the balancer settings document is missing, these are the defaults, which will be used.
- */
- void _useDefaultBalancerSettings();
-
- /**
* Reloads the chunk sizes configuration from the settings document. Fails if the settings
* document cannot be read or if any setting contains invalid value, in which case the offending
* value will remain unchanged.
*/
Status _refreshChunkSizeSettings(OperationContext* txn);
- /**
- * If the chunk size settings document is missing, these are the defaults, which will be used.
- */
- void _useDefaultChunkSizeSettings();
-
- // Whether auto-balancing of chunks should happen
- AtomicBool _shouldBalance{true};
-
- // The latest read balancer settings (used for the balancer window and secondary throttle) and a
- // mutex to protect its changes
+ // The latest read balancer settings and a mutex to protect its swaps
mutable stdx::mutex _balancerSettingsMutex;
- SettingsType _balancerSettings;
- bool _waitForDelete{false};
- MigrationSecondaryThrottleOptions _secondaryThrottle;
+ BalancerSettingsType _balancerSettings;
// Default value for use for the max chunk size if the setting is not present in the balancer
// configuration
const uint64_t _defaultMaxChunkSizeBytes;
- // Max chunk size after which a chunk would be considered jumbo and won't be moved
+ // Max chunk size after which a chunk would be considered jumbo and won't be moved. This value
+ // is read on the critical path after each write operation, that's why it is cached.
AtomicUInt64 _maxChunkSizeBytes;
};
diff --git a/src/mongo/s/balancer/balancer_configuration_test.cpp b/src/mongo/s/balancer/balancer_configuration_test.cpp
new file mode 100644
index 00000000000..ffe95dde645
--- /dev/null
+++ b/src/mongo/s/balancer/balancer_configuration_test.cpp
@@ -0,0 +1,263 @@
+/**
+ * Copyright (C) 2016 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.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include <boost/optional.hpp>
+#include <vector>
+
+#include "mongo/bson/bsonmisc.h"
+#include "mongo/client/remote_command_targeter_mock.h"
+#include "mongo/db/namespace_string.h"
+#include "mongo/db/query/lite_parsed_query.h"
+#include "mongo/executor/remote_command_request.h"
+#include "mongo/rpc/metadata/repl_set_metadata.h"
+#include "mongo/rpc/metadata/server_selection_metadata.h"
+#include "mongo/s/balancer/balancer_configuration.h"
+#include "mongo/s/catalog/catalog_manager.h"
+#include "mongo/s/sharding_test_fixture.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/net/hostandport.h"
+
+namespace mongo {
+namespace {
+
+using executor::RemoteCommandRequest;
+using std::vector;
+using unittest::assertGet;
+
+const BSONObj kReplSecondaryOkMetadata{[] {
+ BSONObjBuilder o;
+ o.appendElements(rpc::ServerSelectionMetadata(true, boost::none).toBSON());
+ o.append(rpc::kReplSetMetadataFieldName, 1);
+ return o.obj();
+}()};
+
+class BalancerConfigurationTestFixture : public ShardingTestFixture {
+protected:
+ /**
+ * Expects a correct find command to be dispatched for the config.settings namespace and returns
+ * the specified result. If an empty boost::optional is passed, returns an empty results.
+ */
+ void expectSettingsQuery(StringData key, StatusWith<boost::optional<BSONObj>> result) {
+ onFindCommand([&](const RemoteCommandRequest& request) {
+ ASSERT_EQUALS(kReplSecondaryOkMetadata, request.metadata);
+
+ const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String());
+ ASSERT_EQ(nss.ns(), "config.settings");
+
+ auto query =
+ assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false));
+
+ ASSERT_EQ(query->ns(), "config.settings");
+ ASSERT_EQ(query->getFilter(), BSON("_id" << key));
+
+ checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm);
+
+ if (!result.isOK()) {
+ return StatusWith<vector<BSONObj>>(result.getStatus());
+ }
+
+ if (result.getValue()) {
+ return StatusWith<vector<BSONObj>>(vector<BSONObj>{*(result.getValue())});
+ }
+
+ return StatusWith<vector<BSONObj>>(vector<BSONObj>{});
+ });
+ }
+};
+
+TEST_F(BalancerConfigurationTestFixture, NoConfigurationDocuments) {
+ configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
+
+ BalancerConfiguration config(1024 * 1024ULL);
+
+ auto future = launchAsync([&] { ASSERT_OK(config.refreshAndCheck(operationContext())); });
+
+ expectSettingsQuery(BalancerSettingsType::kKey, boost::optional<BSONObj>());
+ expectSettingsQuery(ChunkSizeSettingsType::kKey, boost::optional<BSONObj>());
+
+ future.timed_get(kFutureTimeout);
+
+ ASSERT(config.isBalancerActive());
+ ASSERT_EQ(MigrationSecondaryThrottleOptions::kDefault,
+ config.getSecondaryThrottle().getSecondaryThrottle());
+ ASSERT_EQ(1024 * 1024ULL, config.getMaxChunkSizeBytes());
+}
+
+TEST_F(BalancerConfigurationTestFixture, ChunkSizeSettingsDocumentOnly) {
+ configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
+
+ BalancerConfiguration config(1024 * 1024ULL);
+
+ auto future = launchAsync([&] { ASSERT_OK(config.refreshAndCheck(operationContext())); });
+
+ expectSettingsQuery(BalancerSettingsType::kKey, boost::optional<BSONObj>());
+ expectSettingsQuery(ChunkSizeSettingsType::kKey, boost::optional<BSONObj>(BSON("value" << 3)));
+
+ future.timed_get(kFutureTimeout);
+
+ ASSERT(config.isBalancerActive());
+ ASSERT_EQ(MigrationSecondaryThrottleOptions::kDefault,
+ config.getSecondaryThrottle().getSecondaryThrottle());
+ ASSERT_EQ(3 * 1024 * 1024ULL, config.getMaxChunkSizeBytes());
+}
+
+TEST_F(BalancerConfigurationTestFixture, BalancerSettingsDocumentOnly) {
+ configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
+
+ BalancerConfiguration config(1024 * 1024ULL);
+
+ auto future = launchAsync([&] { ASSERT_OK(config.refreshAndCheck(operationContext())); });
+
+ expectSettingsQuery(BalancerSettingsType::kKey,
+ boost::optional<BSONObj>(BSON("stopped" << true)));
+ expectSettingsQuery(ChunkSizeSettingsType::kKey, boost::optional<BSONObj>());
+
+ future.timed_get(kFutureTimeout);
+
+ ASSERT(!config.isBalancerActive());
+ ASSERT_EQ(MigrationSecondaryThrottleOptions::kDefault,
+ config.getSecondaryThrottle().getSecondaryThrottle());
+ ASSERT_EQ(1024 * 1024ULL, config.getMaxChunkSizeBytes());
+}
+
+TEST(BalancerSettingsType, BalancerDisabled) {
+ BalancerSettingsType settings =
+ assertGet(BalancerSettingsType::fromBSON(BSON("stopped" << true)));
+ ASSERT(!settings.shouldBalance());
+}
+
+TEST(BalancerSettingsType, BalancingWindowStartLessThanStop) {
+ BalancerSettingsType settings =
+ assertGet(BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("start"
+ << "9:00"
+ << "stop"
+ << "19:00"))));
+
+ ASSERT(settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(9) + boost::posix_time::minutes(0))));
+ ASSERT(settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(10) + boost::posix_time::minutes(30))));
+ ASSERT(settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(19) + boost::posix_time::minutes(0))));
+
+ ASSERT(!settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(8) + boost::posix_time::minutes(59))));
+ ASSERT(!settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(19) + boost::posix_time::minutes(1))));
+}
+
+TEST(BalancerSettingsType, BalancingWindowStopLessThanStart) {
+ BalancerSettingsType settings =
+ assertGet(BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("start"
+ << "23:00"
+ << "stop"
+ << "8:00"))));
+
+ ASSERT(settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(23) + boost::posix_time::minutes(0))));
+ ASSERT(settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(2) + boost::posix_time::minutes(30))));
+ ASSERT(settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(7) + boost::posix_time::minutes(59))));
+
+ ASSERT(!settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(8) + boost::posix_time::minutes(1))));
+ ASSERT(!settings.isTimeInBalancingWindow(boost::posix_time::ptime(
+ currentDate(), boost::posix_time::hours(22) + boost::posix_time::minutes(00))));
+}
+
+TEST(BalancerSettingsType, InvalidBalancingWindowStartEqualsStop) {
+ ASSERT_NOT_OK(
+ BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("start"
+ << "00:00"
+ << "stop"
+ << "00:00"))).getStatus());
+}
+
+TEST(BalancerSettingsType, InvalidBalancingWindowTimeFormat) {
+ ASSERT_NOT_OK(BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("start"
+ << "23"
+ << "stop"
+ << "6"))).getStatus());
+
+ ASSERT_NOT_OK(BalancerSettingsType::fromBSON(
+ BSON("activeWindow" << BSON("start" << 23LL << "stop"
+ << "6:00"))).getStatus());
+
+ ASSERT_NOT_OK(
+ BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("start"
+ << "23:00"
+ << "stop" << 6LL))).getStatus());
+}
+
+TEST(BalancerSettingsType, InvalidBalancingWindowFormat) {
+ ASSERT_NOT_OK(
+ BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("begin"
+ << "23:00"
+ << "stop"
+ << "6:00"))).getStatus());
+
+ ASSERT_NOT_OK(
+ BalancerSettingsType::fromBSON(BSON("activeWindow" << BSON("start"
+ << "23:00"
+ << "end"
+ << "6:00"))).getStatus());
+}
+
+TEST(ChunkSizeSettingsType, NormalValues) {
+ ASSERT_EQ(
+ 1024 * 1024ULL,
+ assertGet(ChunkSizeSettingsType::fromBSON(BSON("value" << 1))).getMaxChunkSizeBytes());
+ ASSERT_EQ(
+ 10 * 1024 * 1024ULL,
+ assertGet(ChunkSizeSettingsType::fromBSON(BSON("value" << 10))).getMaxChunkSizeBytes());
+ ASSERT_EQ(
+ 1024 * 1024 * 1024ULL,
+ assertGet(ChunkSizeSettingsType::fromBSON(BSON("value" << 1024))).getMaxChunkSizeBytes());
+}
+
+TEST(ChunkSizeSettingsType, BackwardsCompatibilityDueToExtraKeys) {
+ ASSERT_EQ(1024 * 1024ULL,
+ assertGet(ChunkSizeSettingsType::fromBSON(BSON("value" << 1 << "SomeFutureKey"
+ << "SomeFutureValue")))
+ .getMaxChunkSizeBytes());
+}
+
+TEST(ChunkSizeSettingsType, IllegalValues) {
+ ASSERT_NOT_OK(ChunkSizeSettingsType::fromBSON(BSON("value" << 0)).getStatus());
+ ASSERT_NOT_OK(ChunkSizeSettingsType::fromBSON(BSON("value" << -1)).getStatus());
+ ASSERT_NOT_OK(ChunkSizeSettingsType::fromBSON(BSON("value" << 1025)).getStatus());
+ ASSERT_NOT_OK(ChunkSizeSettingsType::fromBSON(BSON("value"
+ << "WrongType")).getStatus());
+ ASSERT_NOT_OK(ChunkSizeSettingsType::fromBSON(BSON("IllegalKey" << 1)).getStatus());
+}
+
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/s/catalog/SConscript b/src/mongo/s/catalog/SConscript
index c79fff0d7ab..f2be9260e3b 100644
--- a/src/mongo/s/catalog/SConscript
+++ b/src/mongo/s/catalog/SConscript
@@ -20,7 +20,6 @@ env.Library(
'type_lockpings.cpp',
'type_locks.cpp',
'type_mongos.cpp',
- 'type_settings.cpp',
'type_shard.cpp',
'type_tags.cpp',
],
@@ -52,7 +51,6 @@ env.CppUnitTest(
'type_lockpings_test.cpp',
'type_locks_test.cpp',
'type_mongos_test.cpp',
- 'type_settings_test.cpp',
'type_shard_test.cpp',
'type_tags_test.cpp',
],
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp
index 7971a0ce846..8fc2cf1f984 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp
@@ -686,7 +686,7 @@ TEST_F(ShardCollectionTest, withInitialData) {
ASSERT_EQUALS(keyPattern.toBSON(), request.cmdObj["keyPattern"].Obj());
ASSERT_EQUALS(keyPattern.getKeyPattern().globalMin(), request.cmdObj["min"].Obj());
ASSERT_EQUALS(keyPattern.getKeyPattern().globalMax(), request.cmdObj["max"].Obj());
- ASSERT_EQUALS(BalancerConfiguration::kDefaultMaxChunkSizeBytes,
+ ASSERT_EQUALS(ChunkSizeSettingsType::kDefaultMaxChunkSizeBytes,
static_cast<uint64_t>(request.cmdObj["maxChunkSizeBytes"].numberLong()));
ASSERT_EQUALS(0, request.cmdObj["maxSplitPoints"].numberLong());
ASSERT_EQUALS(0, request.cmdObj["maxChunkObjects"].numberLong());
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
index 45d7fdba010..a998c34e935 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
@@ -48,7 +48,6 @@
#include "mongo/s/catalog/type_collection.h"
#include "mongo/s/catalog/type_database.h"
#include "mongo/s/catalog/type_shard.h"
-#include "mongo/s/catalog/type_settings.h"
#include "mongo/s/catalog/type_tags.h"
#include "mongo/s/chunk_version.h"
#include "mongo/s/client/shard_registry.h"
@@ -834,102 +833,6 @@ TEST_F(CatalogManagerReplSetTest, RunUserManagementWriteCommandNotMasterRetrySuc
future.timed_get(kFutureTimeout);
}
-TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsBalancerDoc) {
- configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
-
- // sample balancer doc
- SettingsType st1;
- st1.setKey(SettingsType::BalancerDocKey);
- st1.setBalancerStopped(true);
-
- auto future = launchAsync([this] {
- return assertGet(
- catalogManager()->getGlobalSettings(operationContext(), SettingsType::BalancerDocKey));
- });
-
- onFindCommand([this, st1](const RemoteCommandRequest& request) {
- ASSERT_EQUALS(kReplSecondaryOkMetadata, request.metadata);
-
- const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String());
- ASSERT_EQ(nss.ns(), SettingsType::ConfigNS);
-
- auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false));
-
- ASSERT_EQ(query->ns(), SettingsType::ConfigNS);
- ASSERT_EQ(query->getFilter(), BSON(SettingsType::key(SettingsType::BalancerDocKey)));
-
- checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm);
-
- return vector<BSONObj>{st1.toBSON()};
- });
-
- const auto& actualBalSettings =
- assertGet(SettingsType::fromBSON(future.timed_get(kFutureTimeout)));
- ASSERT_EQ(actualBalSettings.toBSON(), st1.toBSON());
-}
-
-TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsChunkSizeDoc) {
- configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
-
- // sample chunk size doc
- SettingsType st1;
- st1.setKey(SettingsType::ChunkSizeDocKey);
- st1.setChunkSizeMB(80);
-
- auto future = launchAsync([this] {
- return assertGet(
- catalogManager()->getGlobalSettings(operationContext(), SettingsType::ChunkSizeDocKey));
- });
-
- onFindCommand([this, st1](const RemoteCommandRequest& request) {
- ASSERT_EQUALS(kReplSecondaryOkMetadata, request.metadata);
-
- const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String());
- ASSERT_EQ(nss.ns(), SettingsType::ConfigNS);
-
- auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false));
-
- ASSERT_EQ(query->ns(), SettingsType::ConfigNS);
- ASSERT_EQ(query->getFilter(), BSON(SettingsType::key(SettingsType::ChunkSizeDocKey)));
-
- checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm);
-
- return vector<BSONObj>{st1.toBSON()};
- });
-
- const auto& actualBalSettings =
- assertGet(SettingsType::fromBSON(future.timed_get(kFutureTimeout)));
- ASSERT_EQ(actualBalSettings.toBSON(), st1.toBSON());
-}
-
-TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsNonExistent) {
- configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
-
- auto future = launchAsync([this] {
- auto status =
- catalogManager()->getGlobalSettings(operationContext(), SettingsType::ChunkSizeDocKey);
- ASSERT_EQ(status.getStatus(), ErrorCodes::NoMatchingDocument);
- });
-
- onFindCommand([this](const RemoteCommandRequest& request) {
- ASSERT_EQUALS(kReplSecondaryOkMetadata, request.metadata);
-
- const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String());
- ASSERT_EQ(nss.ns(), SettingsType::ConfigNS);
-
- auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false));
-
- ASSERT_EQ(query->ns(), SettingsType::ConfigNS);
- ASSERT_EQ(query->getFilter(), BSON(SettingsType::key(SettingsType::ChunkSizeDocKey)));
-
- checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm);
-
- return vector<BSONObj>{};
- });
-
- future.timed_get(kFutureTimeout);
-}
-
TEST_F(CatalogManagerReplSetTest, GetCollectionsValidResultsNoDb) {
configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1"));
diff --git a/src/mongo/s/catalog/type_settings.cpp b/src/mongo/s/catalog/type_settings.cpp
deleted file mode 100644
index b67fa4af6ec..00000000000
--- a/src/mongo/s/catalog/type_settings.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/**
- * Copyright (C) 2012 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.
- */
-
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/s/catalog/type_settings.h"
-
-#include <memory>
-
-#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/stdx/memory.h"
-#include "mongo/util/assert_util.h"
-#include "mongo/util/log.h"
-#include "mongo/util/mongoutils/str.h"
-#include "mongo/util/time_support.h"
-
-namespace mongo {
-
-const std::string SettingsType::ConfigNS = "config.settings";
-const std::string SettingsType::BalancerDocKey("balancer");
-const std::string SettingsType::ChunkSizeDocKey("chunksize");
-
-const BSONField<std::string> SettingsType::key("_id");
-const BSONField<long long> SettingsType::chunkSizeMB("value");
-const BSONField<bool> SettingsType::balancerStopped("stopped");
-const BSONField<BSONObj> SettingsType::balancerActiveWindow("activeWindow");
-const BSONField<bool> SettingsType::deprecated_secondaryThrottle("_secondaryThrottle");
-const BSONField<BSONObj> SettingsType::migrationWriteConcern("_secondaryThrottle");
-const BSONField<bool> SettingsType::waitForDelete("_waitForDelete");
-
-StatusWith<SettingsType> SettingsType::fromBSON(const BSONObj& source) {
- SettingsType settings;
-
- {
- std::string settingsKey;
- Status status = bsonExtractStringField(source, key.name(), &settingsKey);
- if (!status.isOK())
- return status;
- settings._key = settingsKey;
- }
-
- if (settings._key == ChunkSizeDocKey) {
- long long settingsChunkSizeMB;
- Status status = bsonExtractIntegerField(source, chunkSizeMB.name(), &settingsChunkSizeMB);
- if (!status.isOK())
- return status;
- settings._chunkSizeMB = settingsChunkSizeMB;
- } else if (settings._key == BalancerDocKey) {
- {
- bool settingsBalancerStopped;
- Status status = bsonExtractBooleanFieldWithDefault(
- source, balancerStopped.name(), false, &settingsBalancerStopped);
- if (!status.isOK())
- return status;
- settings._balancerStopped = settingsBalancerStopped;
- }
-
- {
- BSONElement settingsBalancerActiveWindowElem;
- Status status = bsonExtractTypedField(
- source, balancerActiveWindow.name(), Object, &settingsBalancerActiveWindowElem);
- if (status != ErrorCodes::NoSuchKey) {
- if (!status.isOK())
- return status;
- StatusWith<BoostTimePair> timePairResult =
- settings._parseBalancingWindow(settingsBalancerActiveWindowElem.Obj());
- if (!timePairResult.isOK())
- return timePairResult.getStatus();
- settings._balancerActiveWindow = timePairResult.getValue();
- }
- }
-
- {
- BSONElement settingsMigrationWriteConcernElem;
- Status status = bsonExtractTypedField(
- source, migrationWriteConcern.name(), Object, &settingsMigrationWriteConcernElem);
- if (status == ErrorCodes::TypeMismatch) {
- bool settingsSecondaryThrottle;
- status = bsonExtractBooleanFieldWithDefault(
- source, deprecated_secondaryThrottle.name(), true, &settingsSecondaryThrottle);
- if (!status.isOK())
- return status;
- settings._secondaryThrottle = settingsSecondaryThrottle;
- } else if (status != ErrorCodes::NoSuchKey) {
- if (!status.isOK())
- return status;
- settings._migrationWriteConcern = WriteConcernOptions();
- status =
- settings._migrationWriteConcern->parse(settingsMigrationWriteConcernElem.Obj());
- if (!status.isOK())
- return status;
- }
- }
-
- {
- bool settingsWaitForDelete;
- Status status =
- bsonExtractBooleanField(source, waitForDelete.name(), &settingsWaitForDelete);
- if (status != ErrorCodes::NoSuchKey) {
- if (!status.isOK())
- return status;
- settings._waitForDelete = settingsWaitForDelete;
- }
- }
- }
-
- return settings;
-}
-
-Status SettingsType::validate() const {
- if (!_key.is_initialized() || _key->empty()) {
- return Status(ErrorCodes::NoSuchKey, str::stream() << "missing " << key.name() << " field");
- }
-
- if (_key == ChunkSizeDocKey) {
- if (!(getChunkSizeMB() > 0)) {
- return Status(ErrorCodes::BadValue,
- str::stream() << "chunksize specified in " << chunkSizeMB.name()
- << " field must be greater than zero");
- }
- } else if (_key == BalancerDocKey) {
- if (_secondaryThrottle.is_initialized() && _migrationWriteConcern.is_initialized()) {
- return Status(ErrorCodes::BadValue,
- str::stream() << "cannot have both secondary throttle and "
- << "migration write concern set at the same time");
- }
- } else {
- return Status(ErrorCodes::UnsupportedFormat,
- str::stream() << "unsupported key in " << key.name() << " field");
- }
-
- return Status::OK();
-}
-
-BSONObj SettingsType::toBSON() const {
- BSONObjBuilder builder;
-
- if (_key)
- builder.append(key(), getKey());
- if (_chunkSizeMB)
- builder.append(chunkSizeMB(), getChunkSizeMB());
- if (_balancerStopped)
- builder.append(balancerStopped(), getBalancerStopped());
-
- // These two are mutually exclusive
- if (_secondaryThrottle)
- builder.append(deprecated_secondaryThrottle(), *_secondaryThrottle);
- if (_migrationWriteConcern)
- builder.append(migrationWriteConcern(), _migrationWriteConcern->toBSON());
-
- if (_waitForDelete)
- builder.append(waitForDelete(), getWaitForDelete());
-
- return builder.obj();
-}
-
-std::string SettingsType::toString() const {
- return toBSON().toString();
-}
-
-StatusWith<BoostTimePair> SettingsType::_parseBalancingWindow(const BSONObj& balancingWindowObj) {
- if (balancingWindowObj.isEmpty()) {
- return Status(ErrorCodes::BadValue, "'activeWindow' can't be empty");
- }
-
- // check if both 'start' and 'stop' are present
- std::string start = balancingWindowObj.getField("start").str();
- std::string stop = balancingWindowObj.getField("stop").str();
- if (start.empty() || stop.empty()) {
- return Status(ErrorCodes::BadValue,
- str::stream() << "must specify both start and end of balancing window: "
- << balancingWindowObj);
- }
-
- // check that both 'start' and 'stop' are valid time-of-day
- boost::posix_time::ptime startTime, stopTime;
- if (!toPointInTime(start, &startTime) || !toPointInTime(stop, &stopTime)) {
- return Status(ErrorCodes::BadValue,
- str::stream() << balancerActiveWindow.name() << " format is "
- << " { start: \"hh:mm\" , stop: \"hh:mm\" }");
- }
-
- return std::make_pair(startTime, stopTime);
-}
-
-bool SettingsType::inBalancingWindow(const boost::posix_time::ptime& now) const {
- if (!_balancerActiveWindow.is_initialized()) {
- return true;
- }
- const boost::posix_time::ptime& startTime = _balancerActiveWindow->first;
- const boost::posix_time::ptime& stopTime = _balancerActiveWindow->second;
-
- LOG(1).stream() << "inBalancingWindow: "
- << " now: " << now << " startTime: " << startTime << " stopTime: " << stopTime;
-
- // allow balancing if during the activeWindow
- // note that a window may be open during the night
- if (stopTime > startTime) {
- if ((now >= startTime) && (now <= stopTime)) {
- return true;
- }
- } else if (startTime > stopTime) {
- if ((now >= startTime) || (now <= stopTime)) {
- return true;
- }
- }
-
- return false;
-}
-
-void SettingsType::setKey(const std::string& key) {
- invariant(!key.empty());
- _key = key;
-}
-
-void SettingsType::setChunkSizeMB(const long long chunkSizeMB) {
- invariant(_key == ChunkSizeDocKey);
- invariant(chunkSizeMB > 0);
- _chunkSizeMB = chunkSizeMB;
-}
-
-void SettingsType::setBalancerStopped(const bool balancerStopped) {
- invariant(_key == BalancerDocKey);
- _balancerStopped = balancerStopped;
-}
-
-void SettingsType::setBalancerActiveWindow(const BSONObj& balancerActiveWindow) {
- invariant(_key == BalancerDocKey);
- StatusWith<BoostTimePair> timePairResult = _parseBalancingWindow(balancerActiveWindow);
- invariant(timePairResult.isOK());
- _balancerActiveWindow = timePairResult.getValue();
-}
-
-void SettingsType::setWaitForDelete(const bool waitForDelete) {
- invariant(_key == BalancerDocKey);
- _waitForDelete = waitForDelete;
-}
-
-} // namespace mongo
diff --git a/src/mongo/s/catalog/type_settings.h b/src/mongo/s/catalog/type_settings.h
deleted file mode 100644
index 464bf7efa50..00000000000
--- a/src/mongo/s/catalog/type_settings.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * Copyright (C) 2012 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/date_time/posix_time/posix_time.hpp>
-#include <boost/optional.hpp>
-#include <string>
-#include <utility>
-
-#include "mongo/bson/bson_field.h"
-#include "mongo/db/write_concern_options.h"
-
-namespace mongo {
-
-class BSONObj;
-template <typename T>
-class StatusWith;
-
-using BoostTimePair = std::pair<boost::posix_time::ptime, boost::posix_time::ptime>;
-
-/**
- * This class represents the layout and contents of documents contained in the
- * config.settings collection. All manipulation of documents coming from that
- * collection should be done with this class.
- *
- * Usage Example:
- *
- * // Contact the config. 'conn' has been obtained before.
- * DBClientBase* conn;
- * BSONObj query = QUERY(SettingsType::exampleField(SettingsType::ExampleFieldName));
- * exampleDoc = conn->findOne(SettingsType::ConfigNS, query);
- *
- * // Process the response.
- * StatusWith<SettingsType> exampleResult = SettingsType::fromBSON(exampleDoc);
- * if (!exampleResult.isOK()) {
- * if (exampleResult.getStatus() == ErrorCodes::NoSuchKey) {
- * // exampleDoc has no key set or is empty
- * }
- * // handle error -- exampleResult.getStatus()
- * }
- * SettingsType exampleType = exampleResult.getValue();
- */
-class SettingsType {
-public:
- // Name of the settings collection in the config server.
- static const std::string ConfigNS;
-
- static const std::string BalancerDocKey;
- static const std::string ChunkSizeDocKey;
-
- // Field names and types in the settings collection type.
- static const BSONField<std::string> key;
- static const BSONField<long long> chunkSizeMB;
- static const BSONField<bool> balancerStopped;
- static const BSONField<BSONObj> balancerActiveWindow;
- static const BSONField<bool> deprecated_secondaryThrottle;
- static const BSONField<BSONObj> migrationWriteConcern;
- static const BSONField<bool> waitForDelete;
-
- /**
- * Returns OK if all mandatory fields have been set and their corresponding
- * values are valid.
- */
- Status validate() const;
-
- /**
- * Returns the BSON representation of the entry.
- */
- BSONObj toBSON() const;
-
- /**
- * Constructs a new ShardType object from BSON.
- * Also does validation of the contents.
- */
- static StatusWith<SettingsType> fromBSON(const BSONObj& source);
-
- /**
- * Returns a std::string representation of the current internal state.
- */
- std::string toString() const;
-
- /**
- * Returns true if either 'now' is in the balancing window or
- * if no balancing window exists.
- */
- bool inBalancingWindow(const boost::posix_time::ptime& now) const;
-
- bool isKeySet() const {
- return _key.is_initialized();
- }
- const std::string& getKey() const {
- return _key.get();
- }
- void setKey(const std::string& key);
-
- bool isChunkSizeMBSet() const {
- return _chunkSizeMB.is_initialized();
- }
- long long getChunkSizeMB() const {
- return _chunkSizeMB.get();
- }
- void setChunkSizeMB(const long long chunkSizeMB);
-
- bool isBalancerStoppedSet() const {
- return _balancerStopped.is_initialized();
- }
- bool getBalancerStopped() const {
- return _balancerStopped.get();
- }
- void setBalancerStopped(const bool balancerStopped);
-
- bool isBalancerActiveWindowSet() const {
- return _balancerActiveWindow.is_initialized();
- }
- const BoostTimePair& getBalancerActiveWindow() const {
- return _balancerActiveWindow.get();
- }
- void setBalancerActiveWindow(const BSONObj& balancerActiveWindow);
-
- bool isWaitForDeleteSet() const {
- return _waitForDelete.is_initialized();
- }
- bool getWaitForDelete() const {
- return _waitForDelete.get();
- }
- void setWaitForDelete(const bool waitForDelete);
-
-private:
- /**
- * Used to parse balancing 'activeWindow'.
- * See '_balancerActiveWindow' member variable doc comments below.
- */
- StatusWith<BoostTimePair> _parseBalancingWindow(const BSONObj& balancingWindowObj);
-
- // Convention: (M)andatory, (O)ptional, (S)pecial rule.
-
- // (M) key determining the type of options to use
- boost::optional<std::string> _key;
-
- // (S) size of the chunks in our cluster in MB
- // Required if key is chunkSize
- boost::optional<long long> _chunkSizeMB;
-
- // (O) is balancer enabled or disabled (default)
- // Defaults to false.
- boost::optional<bool> _balancerStopped;
-
- // (O) if present, balancerActiveWindow is an interval during the day
- // when the balancer should be active.
- // Stored as (<start time>, <stop time>) pair. strftime format is %H:%M
- boost::optional<BoostTimePair> _balancerActiveWindow;
-
- // (O) only migrate chunks as fast as at least one secondary can keep up with
- boost::optional<bool> _secondaryThrottle;
-
- // (O) detailed write concern for *individual* writes during migration.
- // From side: deletes during cleanup.
- // To side: deletes to clear the incoming range, deletes to undo migration at abort,
- // and writes during cloning.
- boost::optional<WriteConcernOptions> _migrationWriteConcern;
-
- // (O) synchronous migration cleanup.
- boost::optional<bool> _waitForDelete;
-};
-
-} // namespace mongo
diff --git a/src/mongo/s/catalog/type_settings_test.cpp b/src/mongo/s/catalog/type_settings_test.cpp
deleted file mode 100644
index f5abfe88dfe..00000000000
--- a/src/mongo/s/catalog/type_settings_test.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * Copyright (C) 2012 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_settings.h"
-
-#include "mongo/base/status_with.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/unittest/unittest.h"
-
-namespace {
-
-using namespace mongo;
-
-TEST(SettingsType, MissingKey) {
- BSONObj objNoKey = BSONObj();
- StatusWith<SettingsType> result = SettingsType::fromBSON(objNoKey);
- ASSERT_FALSE(result.isOK());
- ASSERT_EQUALS(result.getStatus(), ErrorCodes::NoSuchKey);
-}
-
-TEST(SettingsType, ChunkSize) {
- BSONObj objChunkSizeZero =
- BSON(SettingsType::key(SettingsType::ChunkSizeDocKey) << SettingsType::chunkSizeMB(0));
- StatusWith<SettingsType> result = SettingsType::fromBSON(objChunkSizeZero);
- ASSERT(result.isOK());
- SettingsType settings = result.getValue();
- ASSERT_EQUALS(settings.getChunkSizeMB(), 0);
- Status validationStatus = settings.validate();
- ASSERT_FALSE(validationStatus.isOK());
- ASSERT_EQUALS(validationStatus, ErrorCodes::BadValue);
-}
-
-TEST(SettingsType, UnsupportedSetting) {
- BSONObj objBadSetting = BSON(SettingsType::key("badsetting"));
- StatusWith<SettingsType> result = SettingsType::fromBSON(objBadSetting);
- ASSERT(result.isOK());
- SettingsType settings = result.getValue();
- Status validationStatus = settings.validate();
- ASSERT_FALSE(validationStatus.isOK());
- ASSERT_EQUALS(validationStatus, ErrorCodes::UnsupportedFormat);
-}
-
-TEST(SettingsType, InvalidBalancerWindow) {
- BSONObj objBalancerBadKeys = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("begin"
- << "23:00"
- << "end"
- << "6:00")));
- StatusWith<SettingsType> result = SettingsType::fromBSON(objBalancerBadKeys);
- ASSERT_FALSE(result.isOK());
-
- BSONObj objBalancerBadTimes = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("start"
- << "23"
- << "stop"
- << "6")));
- result = SettingsType::fromBSON(objBalancerBadTimes);
- ASSERT_FALSE(result.isOK());
-}
-
-TEST(SettingsType, ValidValues) {
- BSONObj objChunkSize =
- BSON(SettingsType::key(SettingsType::ChunkSizeDocKey) << SettingsType::chunkSizeMB(1));
- StatusWith<SettingsType> result = SettingsType::fromBSON(objChunkSize);
- SettingsType settings = result.getValue();
- ASSERT(result.isOK());
- Status validationStatus = settings.validate();
- ASSERT(validationStatus.isOK());
- ASSERT_EQUALS(settings.getKey(), SettingsType::ChunkSizeDocKey);
- ASSERT_EQUALS(settings.getChunkSizeMB(), 1);
-
- BSONObj objBalancer = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerStopped(true)
- << SettingsType::balancerActiveWindow(BSON("start"
- << "23:00"
- << "stop"
- << "6:00")));
- result = SettingsType::fromBSON(objBalancer);
- settings = result.getValue();
- ASSERT(result.isOK());
- validationStatus = settings.validate();
- ASSERT(validationStatus.isOK());
- ASSERT_EQUALS(settings.getKey(), SettingsType::BalancerDocKey);
- ASSERT_EQUALS(settings.getBalancerStopped(), true);
-}
-
-TEST(SettingsType, BadType) {
- BSONObj badTypeObj = BSON(SettingsType::key() << 0);
- StatusWith<SettingsType> result = SettingsType::fromBSON(badTypeObj);
- ASSERT_FALSE(result.isOK());
-}
-
-TEST(SettingsType, BalancingWindow) {
- // T0 < T1 < now < T2 < T3 and Error
- const std::string T0 = "9:00";
- const std::string T1 = "11:00";
- boost::posix_time::ptime now(currentDate(),
- boost::posix_time::hours(13) + boost::posix_time::minutes(48));
- const std::string T2 = "17:00";
- const std::string T3 = "21:30";
- const std::string E = "28:35";
-
- // closed in the past
- BSONObj w1 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("start" << T0 << "stop" << T1)));
- StatusWith<SettingsType> result = SettingsType::fromBSON(w1);
- ASSERT(result.isOK());
- ASSERT_FALSE(result.getValue().inBalancingWindow(now));
-
- // not opened until the future
- BSONObj w2 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("start" << T2 << "stop" << T3)));
- result = SettingsType::fromBSON(w2);
- ASSERT(result.isOK());
- ASSERT_FALSE(result.getValue().inBalancingWindow(now));
-
- // open now
- BSONObj w3 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("start" << T1 << "stop" << T2)));
- result = SettingsType::fromBSON(w3);
- ASSERT(result.isOK());
- ASSERT(result.getValue().inBalancingWindow(now));
-
- // open since last day
- BSONObj w4 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("start" << T3 << "stop" << T2)));
- result = SettingsType::fromBSON(w4);
- ASSERT(result.isOK());
- ASSERT(result.getValue().inBalancingWindow(now));
-
- // bad input should not stop the balancer
-
- // empty window
- BSONObj w5 = BSON(SettingsType::key(SettingsType::BalancerDocKey));
- result = SettingsType::fromBSON(w5);
- ASSERT(result.isOK());
- ASSERT(result.getValue().inBalancingWindow(now));
-
- // missing stop
- BSONObj w6 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("start" << 1)));
- result = SettingsType::fromBSON(w6);
- ASSERT_FALSE(result.isOK());
-
- // missing start
- BSONObj w7 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << SettingsType::balancerActiveWindow(BSON("stop" << 1)));
- result = SettingsType::fromBSON(w7);
- ASSERT_FALSE(result.isOK());
-
- // active window marker missing
- BSONObj w8 = BSON(SettingsType::key(SettingsType::BalancerDocKey)
- << "wrongMarker" << BSON("start" << 1 << "stop" << 1));
- result = SettingsType::fromBSON(w8);
- ASSERT(result.isOK());
- ASSERT(result.getValue().inBalancingWindow(now));
-
- // garbage in window
- BSONObj w9 = BSON(SettingsType::balancerActiveWindow(BSON("start" << T3 << "stop" << E)));
- result = SettingsType::fromBSON(w9);
- ASSERT_FALSE(result.isOK());
-}
-
-} // unnamed namespace
diff --git a/src/mongo/s/mongos_options.cpp b/src/mongo/s/mongos_options.cpp
index 96de91add0e..f0718d12f41 100644
--- a/src/mongo/s/mongos_options.cpp
+++ b/src/mongo/s/mongos_options.cpp
@@ -217,7 +217,7 @@ Status storeMongosOptions(const moe::Environment& params, const std::vector<std:
const uint64_t maxChunkSizeBytes = maxChunkSizeMB * 1024 * 1024;
- if (!BalancerConfiguration::checkMaxChunkSizeValid(maxChunkSizeBytes)) {
+ if (!ChunkSizeSettingsType::checkMaxChunkSizeValid(maxChunkSizeBytes)) {
return Status(ErrorCodes::BadValue, "MaxChunkSize invalid");
}
diff --git a/src/mongo/s/mongos_options.h b/src/mongo/s/mongos_options.h
index e8eb1306b9c..b14c688e6a9 100644
--- a/src/mongo/s/mongos_options.h
+++ b/src/mongo/s/mongos_options.h
@@ -49,7 +49,7 @@ struct MongosGlobalParams {
ConnectionString configdbs;
// The max chunk size after which a chunk will be considered jumbo
- uint64_t maxChunkSizeBytes{BalancerConfiguration::kDefaultMaxChunkSizeBytes};
+ uint64_t maxChunkSizeBytes{ChunkSizeSettingsType::kDefaultMaxChunkSizeBytes};
// Whether auto-splitting is enabled
bool shouldAutoSplit{true};
diff --git a/src/mongo/s/sharding_initialization.cpp b/src/mongo/s/sharding_initialization.cpp
index 17646ac1adb..1be0d0ae45d 100644
--- a/src/mongo/s/sharding_initialization.cpp
+++ b/src/mongo/s/sharding_initialization.cpp
@@ -212,7 +212,7 @@ Status initializeGlobalShardingStateForMongos(OperationContext* txn,
Status initializeGlobalShardingStateForMongod(OperationContext* txn,
const ConnectionString& configCS) {
return initializeGlobalShardingState(
- txn, configCS, BalancerConfiguration::kDefaultMaxChunkSizeBytes, false);
+ txn, configCS, ChunkSizeSettingsType::kDefaultMaxChunkSizeBytes, false);
}
} // namespace mongo
diff --git a/src/mongo/s/sharding_test_fixture.cpp b/src/mongo/s/sharding_test_fixture.cpp
index 886478cc03d..737a996e113 100644
--- a/src/mongo/s/sharding_test_fixture.cpp
+++ b/src/mongo/s/sharding_test_fixture.cpp
@@ -142,7 +142,7 @@ void ShardingTestFixture::setUp() {
stdx::make_unique<CatalogCache>(),
std::move(shardRegistry),
stdx::make_unique<ClusterCursorManager>(_service->getPreciseClockSource()),
- stdx::make_unique<BalancerConfiguration>(BalancerConfiguration::kDefaultMaxChunkSizeBytes),
+ stdx::make_unique<BalancerConfiguration>(ChunkSizeSettingsType::kDefaultMaxChunkSizeBytes),
std::move(executorPool),
_mockNetwork);
}