summaryrefslogtreecommitdiff
path: root/src/mongo/s/catalog/legacy/config_upgrade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/catalog/legacy/config_upgrade.cpp')
-rw-r--r--src/mongo/s/catalog/legacy/config_upgrade.cpp789
1 files changed, 381 insertions, 408 deletions
diff --git a/src/mongo/s/catalog/legacy/config_upgrade.cpp b/src/mongo/s/catalog/legacy/config_upgrade.cpp
index 2ed119d914f..3592d109e2b 100644
--- a/src/mongo/s/catalog/legacy/config_upgrade.cpp
+++ b/src/mongo/s/catalog/legacy/config_upgrade.cpp
@@ -52,519 +52,492 @@
namespace mongo {
- using std::unique_ptr;
- using std::make_pair;
- using std::map;
- using std::string;
- using std::vector;
- using str::stream;
-
- // Implemented in the respective steps' .cpp file
- bool doUpgradeV0ToV7(CatalogManager* catalogManager,
- const VersionType& lastVersionInfo,
- std::string* errMsg);
-
- bool doUpgradeV6ToV7(CatalogManager* catalogManager,
- const VersionType& lastVersionInfo,
- std::string* errMsg);
+using std::unique_ptr;
+using std::make_pair;
+using std::map;
+using std::string;
+using std::vector;
+using str::stream;
+
+// Implemented in the respective steps' .cpp file
+bool doUpgradeV0ToV7(CatalogManager* catalogManager,
+ const VersionType& lastVersionInfo,
+ std::string* errMsg);
+
+bool doUpgradeV6ToV7(CatalogManager* catalogManager,
+ const VersionType& lastVersionInfo,
+ std::string* errMsg);
namespace {
- struct VersionRange {
- VersionRange(int _minCompatibleVersion, int _currentVersion)
- : minCompatibleVersion(_minCompatibleVersion),
- currentVersion(_currentVersion) {
+struct VersionRange {
+ VersionRange(int _minCompatibleVersion, int _currentVersion)
+ : minCompatibleVersion(_minCompatibleVersion), currentVersion(_currentVersion) {}
- }
-
- bool operator==(const VersionRange& other) const {
- return (other.minCompatibleVersion == minCompatibleVersion)
- && (other.currentVersion == currentVersion);
- }
-
- bool operator!=(const VersionRange& other) const {
- return !(*this == other);
- }
-
- int minCompatibleVersion;
- int currentVersion;
- };
-
- enum VersionStatus {
- // No way to upgrade the test version to be compatible with current version
- VersionStatus_Incompatible,
+ bool operator==(const VersionRange& other) const {
+ return (other.minCompatibleVersion == minCompatibleVersion) &&
+ (other.currentVersion == currentVersion);
+ }
- // Current version is compatible with test version
- VersionStatus_Compatible,
+ bool operator!=(const VersionRange& other) const {
+ return !(*this == other);
+ }
- // Test version must be upgraded to be compatible with current version
- VersionStatus_NeedUpgrade
- };
+ int minCompatibleVersion;
+ int currentVersion;
+};
- /**
- * Encapsulates the information needed to register a config upgrade.
- */
- struct UpgradeStep {
- typedef stdx::function<bool(CatalogManager*, const VersionType&, string*)> UpgradeCallback;
+enum VersionStatus {
+ // No way to upgrade the test version to be compatible with current version
+ VersionStatus_Incompatible,
- UpgradeStep(int _fromVersion,
- const VersionRange& _toVersionRange,
- UpgradeCallback _upgradeCallback)
- : fromVersion(_fromVersion),
- toVersionRange(_toVersionRange),
- upgradeCallback(_upgradeCallback) {
+ // Current version is compatible with test version
+ VersionStatus_Compatible,
- }
+ // Test version must be upgraded to be compatible with current version
+ VersionStatus_NeedUpgrade
+};
- // The config version we're upgrading from
- int fromVersion;
+/**
+ * Encapsulates the information needed to register a config upgrade.
+ */
+struct UpgradeStep {
+ typedef stdx::function<bool(CatalogManager*, const VersionType&, string*)> UpgradeCallback;
- // The config version we're upgrading to and the min compatible config version (min, to)
- VersionRange toVersionRange;
+ UpgradeStep(int _fromVersion,
+ const VersionRange& _toVersionRange,
+ UpgradeCallback _upgradeCallback)
+ : fromVersion(_fromVersion),
+ toVersionRange(_toVersionRange),
+ upgradeCallback(_upgradeCallback) {}
- // The upgrade callback which performs the actual upgrade
- UpgradeCallback upgradeCallback;
- };
+ // The config version we're upgrading from
+ int fromVersion;
- typedef map<int, UpgradeStep> ConfigUpgradeRegistry;
+ // The config version we're upgrading to and the min compatible config version (min, to)
+ VersionRange toVersionRange;
- /**
- * Does a sanity-check validation of the registry ensuring three things:
- * 1. All upgrade paths lead to the same minCompatible/currentVersion
- * 2. Our constants match this final version pair
- * 3. There is a zero-version upgrade path
- */
- void validateRegistry(const ConfigUpgradeRegistry& registry) {
- VersionRange maxCompatibleConfigVersionRange(-1, -1);
- bool hasZeroVersionUpgrade = false;
+ // The upgrade callback which performs the actual upgrade
+ UpgradeCallback upgradeCallback;
+};
- for (const auto& upgradeStep : registry) {
- const UpgradeStep& upgrade = upgradeStep.second;
+typedef map<int, UpgradeStep> ConfigUpgradeRegistry;
- if (upgrade.fromVersion == 0) {
- hasZeroVersionUpgrade = true;
- }
+/**
+ * Does a sanity-check validation of the registry ensuring three things:
+ * 1. All upgrade paths lead to the same minCompatible/currentVersion
+ * 2. Our constants match this final version pair
+ * 3. There is a zero-version upgrade path
+ */
+void validateRegistry(const ConfigUpgradeRegistry& registry) {
+ VersionRange maxCompatibleConfigVersionRange(-1, -1);
+ bool hasZeroVersionUpgrade = false;
- if (maxCompatibleConfigVersionRange.currentVersion
- < upgrade.toVersionRange.currentVersion) {
+ for (const auto& upgradeStep : registry) {
+ const UpgradeStep& upgrade = upgradeStep.second;
- maxCompatibleConfigVersionRange = upgrade.toVersionRange;
- }
- else if (maxCompatibleConfigVersionRange.currentVersion
- == upgrade.toVersionRange.currentVersion) {
+ if (upgrade.fromVersion == 0) {
+ hasZeroVersionUpgrade = true;
+ }
- // Make sure all max upgrade paths end up with same version and compatibility
- fassert(16621, maxCompatibleConfigVersionRange == upgrade.toVersionRange);
- }
+ if (maxCompatibleConfigVersionRange.currentVersion <
+ upgrade.toVersionRange.currentVersion) {
+ maxCompatibleConfigVersionRange = upgrade.toVersionRange;
+ } else if (maxCompatibleConfigVersionRange.currentVersion ==
+ upgrade.toVersionRange.currentVersion) {
+ // Make sure all max upgrade paths end up with same version and compatibility
+ fassert(16621, maxCompatibleConfigVersionRange == upgrade.toVersionRange);
}
+ }
- // Make sure we have a zero-version upgrade
- fassert(16622, hasZeroVersionUpgrade);
+ // Make sure we have a zero-version upgrade
+ fassert(16622, hasZeroVersionUpgrade);
- // Make sure our max registered range is the same as our constants
- fassert(16623,
- maxCompatibleConfigVersionRange
- == VersionRange(MIN_COMPATIBLE_CONFIG_VERSION, CURRENT_CONFIG_VERSION));
- }
+ // Make sure our max registered range is the same as our constants
+ fassert(16623,
+ maxCompatibleConfigVersionRange ==
+ VersionRange(MIN_COMPATIBLE_CONFIG_VERSION, CURRENT_CONFIG_VERSION));
+}
- /**
- * Creates a registry of config upgrades used by the code below.
- *
- * MODIFY THIS CODE HERE TO CREATE A NEW UPGRADE PATH FROM X to Y
- * YOU MUST ALSO MODIFY THE VERSION DECLARATIONS IN config_upgrade.h
- *
- * Caveats:
- * - All upgrade paths must eventually lead to the exact same version range of
- * min and max compatible versions.
- * - This resulting version range must be equal to:
- * make_pair(MIN_COMPATIBLE_CONFIG_VERSION, CURRENT_CONFIG_VERSION)
- * - There must always be an upgrade path from the empty version (0) to the latest
- * config version.
- *
- * If any of the above is false, we fassert and fail to start.
- */
- ConfigUpgradeRegistry createRegistry() {
- ConfigUpgradeRegistry registry;
-
- // v0 to v7
- UpgradeStep v0ToV7(0, VersionRange(6, 7), doUpgradeV0ToV7);
- registry.insert(make_pair(v0ToV7.fromVersion, v0ToV7));
-
- // v6 to v7
- UpgradeStep v6ToV7(6, VersionRange(6, 7), doUpgradeV6ToV7);
- registry.insert(make_pair(v6ToV7.fromVersion, v6ToV7));
-
- validateRegistry(registry);
-
- return registry;
- }
+/**
+ * Creates a registry of config upgrades used by the code below.
+ *
+ * MODIFY THIS CODE HERE TO CREATE A NEW UPGRADE PATH FROM X to Y
+ * YOU MUST ALSO MODIFY THE VERSION DECLARATIONS IN config_upgrade.h
+ *
+ * Caveats:
+ * - All upgrade paths must eventually lead to the exact same version range of
+ * min and max compatible versions.
+ * - This resulting version range must be equal to:
+ * make_pair(MIN_COMPATIBLE_CONFIG_VERSION, CURRENT_CONFIG_VERSION)
+ * - There must always be an upgrade path from the empty version (0) to the latest
+ * config version.
+ *
+ * If any of the above is false, we fassert and fail to start.
+ */
+ConfigUpgradeRegistry createRegistry() {
+ ConfigUpgradeRegistry registry;
- /**
- * Checks whether or not a particular cluster version is compatible with our current
- * version and mongodb version. The version is compatible if it falls between the
- * MIN_COMPATIBLE_CONFIG_VERSION and CURRENT_CONFIG_VERSION and is not explicitly excluded.
- *
- * @return a VersionStatus enum indicating compatibility
- */
- VersionStatus isConfigVersionCompatible(const VersionType& versionInfo, string* whyNot) {
- string dummy;
- if (!whyNot) {
- whyNot = &dummy;
- }
+ // v0 to v7
+ UpgradeStep v0ToV7(0, VersionRange(6, 7), doUpgradeV0ToV7);
+ registry.insert(make_pair(v0ToV7.fromVersion, v0ToV7));
- // Check if we're empty
- if (versionInfo.getCurrentVersion() == UpgradeHistory_EmptyVersion) {
- return VersionStatus_NeedUpgrade;
- }
+ // v6 to v7
+ UpgradeStep v6ToV7(6, VersionRange(6, 7), doUpgradeV6ToV7);
+ registry.insert(make_pair(v6ToV7.fromVersion, v6ToV7));
- // Check that we aren't too old
- if (CURRENT_CONFIG_VERSION < versionInfo.getMinCompatibleVersion()) {
+ validateRegistry(registry);
- *whyNot = stream() << "the config version " << CURRENT_CONFIG_VERSION
- << " of our process is too old "
- << "for the detected config version "
- << versionInfo.getMinCompatibleVersion();
+ return registry;
+}
- return VersionStatus_Incompatible;
- }
+/**
+ * Checks whether or not a particular cluster version is compatible with our current
+ * version and mongodb version. The version is compatible if it falls between the
+ * MIN_COMPATIBLE_CONFIG_VERSION and CURRENT_CONFIG_VERSION and is not explicitly excluded.
+ *
+ * @return a VersionStatus enum indicating compatibility
+ */
+VersionStatus isConfigVersionCompatible(const VersionType& versionInfo, string* whyNot) {
+ string dummy;
+ if (!whyNot) {
+ whyNot = &dummy;
+ }
- // Check that the mongo version of this process hasn't been excluded from the cluster
- vector<MongoVersionRange> excludedRanges;
- if (versionInfo.isExcludingMongoVersionsSet() &&
- !MongoVersionRange::parseBSONArray(versionInfo.getExcludingMongoVersions(),
- &excludedRanges,
- whyNot))
- {
+ // Check if we're empty
+ if (versionInfo.getCurrentVersion() == UpgradeHistory_EmptyVersion) {
+ return VersionStatus_NeedUpgrade;
+ }
- *whyNot = stream() << "could not understand excluded version ranges"
- << causedBy(whyNot);
+ // Check that we aren't too old
+ if (CURRENT_CONFIG_VERSION < versionInfo.getMinCompatibleVersion()) {
+ *whyNot = stream() << "the config version " << CURRENT_CONFIG_VERSION
+ << " of our process is too old "
+ << "for the detected config version "
+ << versionInfo.getMinCompatibleVersion();
- return VersionStatus_Incompatible;
- }
+ return VersionStatus_Incompatible;
+ }
- // versionString is the global version of this process
- if (isInMongoVersionRanges(versionString, excludedRanges)) {
+ // Check that the mongo version of this process hasn't been excluded from the cluster
+ vector<MongoVersionRange> excludedRanges;
+ if (versionInfo.isExcludingMongoVersionsSet() &&
+ !MongoVersionRange::parseBSONArray(
+ versionInfo.getExcludingMongoVersions(), &excludedRanges, whyNot)) {
+ *whyNot = stream() << "could not understand excluded version ranges" << causedBy(whyNot);
- // Cast needed here for MSVC compiler issue
- *whyNot = stream() << "not compatible with current config version, version "
- << reinterpret_cast<const char*>(versionString)
- << "has been excluded.";
+ return VersionStatus_Incompatible;
+ }
- return VersionStatus_Incompatible;
- }
+ // versionString is the global version of this process
+ if (isInMongoVersionRanges(versionString, excludedRanges)) {
+ // Cast needed here for MSVC compiler issue
+ *whyNot = stream() << "not compatible with current config version, version "
+ << reinterpret_cast<const char*>(versionString) << "has been excluded.";
- // Check if we need to upgrade
- if (versionInfo.getCurrentVersion() >= CURRENT_CONFIG_VERSION) {
- return VersionStatus_Compatible;
- }
+ return VersionStatus_Incompatible;
+ }
- return VersionStatus_NeedUpgrade;
+ // Check if we need to upgrade
+ if (versionInfo.getCurrentVersion() >= CURRENT_CONFIG_VERSION) {
+ return VersionStatus_Compatible;
}
- // Checks that all config servers are online
- bool _checkConfigServersAlive(const ConnectionString& configLoc, string* errMsg) {
- bool resultOk;
- BSONObj result;
- try {
- ScopedDbConnection conn(configLoc, 30);
- if (conn->type() == ConnectionString::SYNC) {
- // TODO: Dynamic cast is bad, we need a better way of managing this op
- // via the heirarchy (or not)
- SyncClusterConnection* scc = dynamic_cast<SyncClusterConnection*>(conn.get());
- fassert(16729, scc != NULL);
- return scc->prepare(*errMsg);
- }
- else {
- resultOk = conn->runCommand("admin", BSON( "fsync" << 1 ), result);
- }
- conn.done();
- }
- catch (const DBException& e) {
- *errMsg = e.toString();
- return false;
+ return VersionStatus_NeedUpgrade;
+}
+
+// Checks that all config servers are online
+bool _checkConfigServersAlive(const ConnectionString& configLoc, string* errMsg) {
+ bool resultOk;
+ BSONObj result;
+ try {
+ ScopedDbConnection conn(configLoc, 30);
+ if (conn->type() == ConnectionString::SYNC) {
+ // TODO: Dynamic cast is bad, we need a better way of managing this op
+ // via the heirarchy (or not)
+ SyncClusterConnection* scc = dynamic_cast<SyncClusterConnection*>(conn.get());
+ fassert(16729, scc != NULL);
+ return scc->prepare(*errMsg);
+ } else {
+ resultOk = conn->runCommand("admin", BSON("fsync" << 1), result);
}
-
- if (!resultOk) {
- *errMsg = DBClientWithCommands::getLastErrorString(result);
- return false;
- }
-
- return true;
+ conn.done();
+ } catch (const DBException& e) {
+ *errMsg = e.toString();
+ return false;
}
- // Dispatches upgrades based on version to the upgrades registered in the upgrade registry
- bool _nextUpgrade(CatalogManager* catalogManager,
- const ConfigUpgradeRegistry& registry,
- const VersionType& lastVersionInfo,
- VersionType* upgradedVersionInfo,
- string* errMsg) {
+ if (!resultOk) {
+ *errMsg = DBClientWithCommands::getLastErrorString(result);
+ return false;
+ }
- int fromVersion = lastVersionInfo.getCurrentVersion();
+ return true;
+}
- ConfigUpgradeRegistry::const_iterator foundIt = registry.find(fromVersion);
+// Dispatches upgrades based on version to the upgrades registered in the upgrade registry
+bool _nextUpgrade(CatalogManager* catalogManager,
+ const ConfigUpgradeRegistry& registry,
+ const VersionType& lastVersionInfo,
+ VersionType* upgradedVersionInfo,
+ string* errMsg) {
+ int fromVersion = lastVersionInfo.getCurrentVersion();
- if (foundIt == registry.end()) {
+ ConfigUpgradeRegistry::const_iterator foundIt = registry.find(fromVersion);
- *errMsg = stream() << "newer version " << CURRENT_CONFIG_VERSION
- << " of mongo config metadata is required, " << "current version is "
- << fromVersion << ", "
- << "don't know how to upgrade from this version";
+ if (foundIt == registry.end()) {
+ *errMsg = stream() << "newer version " << CURRENT_CONFIG_VERSION
+ << " of mongo config metadata is required, "
+ << "current version is " << fromVersion << ", "
+ << "don't know how to upgrade from this version";
- return false;
- }
+ return false;
+ }
- const UpgradeStep& upgrade = foundIt->second;
- int toVersion = upgrade.toVersionRange.currentVersion;
+ const UpgradeStep& upgrade = foundIt->second;
+ int toVersion = upgrade.toVersionRange.currentVersion;
- log() << "starting next upgrade step from v" << fromVersion << " to v" << toVersion;
+ log() << "starting next upgrade step from v" << fromVersion << " to v" << toVersion;
- // Log begin to config.changelog
- catalogManager->logChange(NULL,
- "starting upgrade of config database",
- VersionType::ConfigNS,
- BSON("from" << fromVersion << "to" << toVersion));
+ // Log begin to config.changelog
+ catalogManager->logChange(NULL,
+ "starting upgrade of config database",
+ VersionType::ConfigNS,
+ BSON("from" << fromVersion << "to" << toVersion));
- if (!upgrade.upgradeCallback(catalogManager, lastVersionInfo, errMsg)) {
- *errMsg = stream() << "error upgrading config database from v"
- << fromVersion << " to v" << toVersion << causedBy(errMsg);
- return false;
- }
+ if (!upgrade.upgradeCallback(catalogManager, lastVersionInfo, errMsg)) {
+ *errMsg = stream() << "error upgrading config database from v" << fromVersion << " to v"
+ << toVersion << causedBy(errMsg);
+ return false;
+ }
- // Get the config version we've upgraded to and make sure it's sane
- Status verifyConfigStatus = getConfigVersion(catalogManager, upgradedVersionInfo);
+ // Get the config version we've upgraded to and make sure it's sane
+ Status verifyConfigStatus = getConfigVersion(catalogManager, upgradedVersionInfo);
- if (!verifyConfigStatus.isOK()) {
- *errMsg = stream() << "failed to validate v" << fromVersion << " config version upgrade"
- << causedBy(verifyConfigStatus);
+ if (!verifyConfigStatus.isOK()) {
+ *errMsg = stream() << "failed to validate v" << fromVersion << " config version upgrade"
+ << causedBy(verifyConfigStatus);
- return false;
- }
-
- catalogManager->logChange(NULL,
- "finished upgrade of config database",
- VersionType::ConfigNS,
- BSON("from" << fromVersion << "to" << toVersion));
- return true;
+ return false;
}
-} // namespace
+ catalogManager->logChange(NULL,
+ "finished upgrade of config database",
+ VersionType::ConfigNS,
+ BSON("from" << fromVersion << "to" << toVersion));
+ return true;
+}
+} // namespace
- /**
- * Returns the config version of the cluster pointed at by the connection string.
- *
- * @return OK if version found successfully, error status if something bad happened.
- */
- Status getConfigVersion(CatalogManager* catalogManager, VersionType* versionInfo) {
- try {
- versionInfo->clear();
- ScopedDbConnection conn(catalogManager->connectionString(), 30);
-
- unique_ptr<DBClientCursor> cursor(_safeCursor(conn->query("config.version",
- BSONObj())));
+/**
+ * Returns the config version of the cluster pointed at by the connection string.
+ *
+ * @return OK if version found successfully, error status if something bad happened.
+ */
+Status getConfigVersion(CatalogManager* catalogManager, VersionType* versionInfo) {
+ try {
+ versionInfo->clear();
- bool hasConfigData = conn->count(ShardType::ConfigNS)
- || conn->count(DatabaseType::ConfigNS)
- || conn->count(CollectionType::ConfigNS);
+ ScopedDbConnection conn(catalogManager->connectionString(), 30);
- if (!cursor->more()) {
+ unique_ptr<DBClientCursor> cursor(_safeCursor(conn->query("config.version", BSONObj())));
- // Version is 1 if we have data, 0 if we're completely empty
- if (hasConfigData) {
- versionInfo->setMinCompatibleVersion(UpgradeHistory_UnreportedVersion);
- versionInfo->setCurrentVersion(UpgradeHistory_UnreportedVersion);
- }
- else {
- versionInfo->setMinCompatibleVersion(UpgradeHistory_EmptyVersion);
- versionInfo->setCurrentVersion(UpgradeHistory_EmptyVersion);
- }
+ bool hasConfigData = conn->count(ShardType::ConfigNS) ||
+ conn->count(DatabaseType::ConfigNS) || conn->count(CollectionType::ConfigNS);
- conn.done();
- return Status::OK();
+ if (!cursor->more()) {
+ // Version is 1 if we have data, 0 if we're completely empty
+ if (hasConfigData) {
+ versionInfo->setMinCompatibleVersion(UpgradeHistory_UnreportedVersion);
+ versionInfo->setCurrentVersion(UpgradeHistory_UnreportedVersion);
+ } else {
+ versionInfo->setMinCompatibleVersion(UpgradeHistory_EmptyVersion);
+ versionInfo->setCurrentVersion(UpgradeHistory_EmptyVersion);
}
- BSONObj versionDoc = cursor->next();
- string errMsg;
+ conn.done();
+ return Status::OK();
+ }
- if (!versionInfo->parseBSON(versionDoc, &errMsg) || !versionInfo->isValid(&errMsg)) {
- conn.done();
+ BSONObj versionDoc = cursor->next();
+ string errMsg;
- return Status(ErrorCodes::UnsupportedFormat,
- stream() << "invalid config version document " << versionDoc
- << causedBy(errMsg));
- }
+ if (!versionInfo->parseBSON(versionDoc, &errMsg) || !versionInfo->isValid(&errMsg)) {
+ conn.done();
- if (cursor->more()) {
- conn.done();
+ return Status(ErrorCodes::UnsupportedFormat,
+ stream() << "invalid config version document " << versionDoc
+ << causedBy(errMsg));
+ }
- return Status(ErrorCodes::RemoteValidationError,
- stream() << "should only have 1 document "
- << "in config.version collection");
- }
+ if (cursor->more()) {
conn.done();
- }
- catch (const DBException& e) {
- return e.toStatus();
- }
- return Status::OK();
+ return Status(ErrorCodes::RemoteValidationError,
+ stream() << "should only have 1 document "
+ << "in config.version collection");
+ }
+ conn.done();
+ } catch (const DBException& e) {
+ return e.toStatus();
}
- bool checkAndUpgradeConfigVersion(CatalogManager* catalogManager,
- bool upgrade,
- VersionType* initialVersionInfo,
- VersionType* versionInfo,
- string* errMsg) {
+ return Status::OK();
+}
+
+bool checkAndUpgradeConfigVersion(CatalogManager* catalogManager,
+ bool upgrade,
+ VersionType* initialVersionInfo,
+ VersionType* versionInfo,
+ string* errMsg) {
+ string dummy;
+ if (!errMsg) {
+ errMsg = &dummy;
+ }
- string dummy;
- if (!errMsg) {
- errMsg = &dummy;
- }
+ Status getConfigStatus = getConfigVersion(catalogManager, versionInfo);
+ if (!getConfigStatus.isOK()) {
+ *errMsg = stream() << "could not load config version for upgrade"
+ << causedBy(getConfigStatus);
+ return false;
+ }
- Status getConfigStatus = getConfigVersion(catalogManager, versionInfo);
- if (!getConfigStatus.isOK()) {
- *errMsg = stream() << "could not load config version for upgrade"
- << causedBy(getConfigStatus);
- return false;
- }
+ versionInfo->cloneTo(initialVersionInfo);
- versionInfo->cloneTo(initialVersionInfo);
+ VersionStatus comp = isConfigVersionCompatible(*versionInfo, errMsg);
- VersionStatus comp = isConfigVersionCompatible(*versionInfo, errMsg);
+ if (comp == VersionStatus_Incompatible)
+ return false;
+ if (comp == VersionStatus_Compatible)
+ return true;
- if (comp == VersionStatus_Incompatible) return false;
- if (comp == VersionStatus_Compatible) return true;
+ invariant(comp == VersionStatus_NeedUpgrade);
- invariant(comp == VersionStatus_NeedUpgrade);
+ //
+ // Our current config version is now greater than the current version, so we should upgrade
+ // if possible.
+ //
- //
- // Our current config version is now greater than the current version, so we should upgrade
- // if possible.
- //
+ // The first empty version is technically an upgrade, but has special semantics
+ bool isEmptyVersion = versionInfo->getCurrentVersion() == UpgradeHistory_EmptyVersion;
- // The first empty version is technically an upgrade, but has special semantics
- bool isEmptyVersion = versionInfo->getCurrentVersion() == UpgradeHistory_EmptyVersion;
+ // First check for the upgrade flag (but no flag is needed if we're upgrading from empty)
+ if (!isEmptyVersion && !upgrade) {
+ *errMsg = stream() << "newer version " << CURRENT_CONFIG_VERSION
+ << " of mongo config metadata is required, "
+ << "current version is " << versionInfo->getCurrentVersion() << ", "
+ << "need to run mongos with --upgrade";
- // First check for the upgrade flag (but no flag is needed if we're upgrading from empty)
- if (!isEmptyVersion && !upgrade) {
- *errMsg = stream() << "newer version " << CURRENT_CONFIG_VERSION
- << " of mongo config metadata is required, " << "current version is "
- << versionInfo->getCurrentVersion() << ", "
- << "need to run mongos with --upgrade";
+ return false;
+ }
- return false;
+ // Contact the config servers to make sure all are online - otherwise we wait a long time
+ // for locks.
+ if (!_checkConfigServersAlive(catalogManager->connectionString(), errMsg)) {
+ if (isEmptyVersion) {
+ *errMsg = stream() << "all config servers must be reachable for initial"
+ << " config database creation" << causedBy(errMsg);
+ } else {
+ *errMsg = stream() << "all config servers must be reachable for config upgrade"
+ << causedBy(errMsg);
}
- // Contact the config servers to make sure all are online - otherwise we wait a long time
- // for locks.
- if (!_checkConfigServersAlive(catalogManager->connectionString(), errMsg)) {
+ return false;
+ }
- if (isEmptyVersion) {
- *errMsg = stream() << "all config servers must be reachable for initial"
- << " config database creation" << causedBy(errMsg);
- }
- else {
- *errMsg = stream() << "all config servers must be reachable for config upgrade"
+ // Check whether or not the balancer is online, if it is online we will not upgrade
+ // (but we will initialize the config server)
+ if (!isEmptyVersion) {
+ auto balSettingsResult = catalogManager->getGlobalSettings(SettingsType::BalancerDocKey);
+ if (balSettingsResult.isOK()) {
+ SettingsType balSettings = balSettingsResult.getValue();
+ if (!balSettings.getBalancerStopped()) {
+ *errMsg = stream() << "balancer must be stopped for config upgrade"
<< causedBy(errMsg);
}
-
- return false;
}
+ }
- // Check whether or not the balancer is online, if it is online we will not upgrade
- // (but we will initialize the config server)
- if (!isEmptyVersion) {
- auto balSettingsResult =
- catalogManager->getGlobalSettings(SettingsType::BalancerDocKey);
- if (balSettingsResult.isOK()) {
- SettingsType balSettings = balSettingsResult.getValue();
- if (!balSettings.getBalancerStopped()) {
- *errMsg = stream() << "balancer must be stopped for config upgrade"
- << causedBy(errMsg);
- }
- }
- }
+ //
+ // Acquire a lock for the upgrade process.
+ //
+ // We want to ensure that only a single mongo process is upgrading the config server at a
+ // time.
+ //
+
+ string whyMessage(stream() << "upgrading config database to new format v"
+ << CURRENT_CONFIG_VERSION);
+ auto lockTimeout = stdx::chrono::milliseconds(20 * 60 * 1000);
+ auto scopedDistLock =
+ catalogManager->getDistLockManager()->lock("configUpgrade", whyMessage, lockTimeout);
+ if (!scopedDistLock.isOK()) {
+ *errMsg = scopedDistLock.getStatus().toString();
+ return false;
+ }
- //
- // Acquire a lock for the upgrade process.
- //
- // We want to ensure that only a single mongo process is upgrading the config server at a
- // time.
- //
+ //
+ // Double-check compatibility inside the upgrade lock
+ // Another process may have won the lock earlier and done the upgrade for us, check
+ // if this is the case.
+ //
+
+ getConfigStatus = getConfigVersion(catalogManager, versionInfo);
+ if (!getConfigStatus.isOK()) {
+ *errMsg = stream() << "could not reload config version for upgrade"
+ << causedBy(getConfigStatus);
+ return false;
+ }
- string whyMessage(stream() << "upgrading config database to new format v"
- << CURRENT_CONFIG_VERSION);
- auto lockTimeout = stdx::chrono::milliseconds(20 * 60 * 1000);
- auto scopedDistLock = catalogManager->getDistLockManager()->lock("configUpgrade",
- whyMessage,
- lockTimeout);
- if (!scopedDistLock.isOK()) {
- *errMsg = scopedDistLock.getStatus().toString();
- return false;
- }
+ versionInfo->cloneTo(initialVersionInfo);
- //
- // Double-check compatibility inside the upgrade lock
- // Another process may have won the lock earlier and done the upgrade for us, check
- // if this is the case.
- //
+ comp = isConfigVersionCompatible(*versionInfo, errMsg);
- getConfigStatus = getConfigVersion(catalogManager, versionInfo);
- if (!getConfigStatus.isOK()) {
- *errMsg = stream() << "could not reload config version for upgrade"
- << causedBy(getConfigStatus);
- return false;
- }
+ if (comp == VersionStatus_Incompatible)
+ return false;
+ if (comp == VersionStatus_Compatible)
+ return true;
- versionInfo->cloneTo(initialVersionInfo);
+ invariant(comp == VersionStatus_NeedUpgrade);
- comp = isConfigVersionCompatible(*versionInfo, errMsg);
+ //
+ // Run through the upgrade steps necessary to bring our config version to the current
+ // version
+ //
- if (comp == VersionStatus_Incompatible) return false;
- if (comp == VersionStatus_Compatible) return true;
+ log() << "starting upgrade of config server from v" << versionInfo->getCurrentVersion()
+ << " to v" << CURRENT_CONFIG_VERSION;
- invariant(comp == VersionStatus_NeedUpgrade);
+ ConfigUpgradeRegistry registry(createRegistry());
+
+ while (versionInfo->getCurrentVersion() < CURRENT_CONFIG_VERSION) {
+ int fromVersion = versionInfo->getCurrentVersion();
//
- // Run through the upgrade steps necessary to bring our config version to the current
- // version
+ // Run the next upgrade process and replace versionInfo with the result of the
+ // upgrade.
//
- log() << "starting upgrade of config server from v" << versionInfo->getCurrentVersion()
- << " to v" << CURRENT_CONFIG_VERSION;
-
- ConfigUpgradeRegistry registry(createRegistry());
-
- while (versionInfo->getCurrentVersion() < CURRENT_CONFIG_VERSION) {
- int fromVersion = versionInfo->getCurrentVersion();
-
- //
- // Run the next upgrade process and replace versionInfo with the result of the
- // upgrade.
- //
-
- if (!_nextUpgrade(catalogManager, registry, *versionInfo, versionInfo, errMsg)) {
- return false;
- }
-
- // Ensure we're making progress here
- if (versionInfo->getCurrentVersion() <= fromVersion) {
+ if (!_nextUpgrade(catalogManager, registry, *versionInfo, versionInfo, errMsg)) {
+ return false;
+ }
- *errMsg = stream() << "bad v" << fromVersion << " config version upgrade, "
- << "version did not increment and is now "
- << versionInfo->getCurrentVersion();
+ // Ensure we're making progress here
+ if (versionInfo->getCurrentVersion() <= fromVersion) {
+ *errMsg = stream() << "bad v" << fromVersion << " config version upgrade, "
+ << "version did not increment and is now "
+ << versionInfo->getCurrentVersion();
- return false;
- }
+ return false;
}
+ }
- invariant(versionInfo->getCurrentVersion() == CURRENT_CONFIG_VERSION);
+ invariant(versionInfo->getCurrentVersion() == CURRENT_CONFIG_VERSION);
- log() << "upgrade of config server to v" << versionInfo->getCurrentVersion()
- << " successful";
+ log() << "upgrade of config server to v" << versionInfo->getCurrentVersion() << " successful";
- return true;
- }
+ return true;
+}
-} // namespace mongo
+} // namespace mongo