diff options
Diffstat (limited to 'src/mongo/s/catalog/legacy/cluster_client_internal.cpp')
-rw-r--r-- | src/mongo/s/catalog/legacy/cluster_client_internal.cpp | 293 |
1 files changed, 140 insertions, 153 deletions
diff --git a/src/mongo/s/catalog/legacy/cluster_client_internal.cpp b/src/mongo/s/catalog/legacy/cluster_client_internal.cpp index 5af263b5e56..c8b60c9c9dc 100644 --- a/src/mongo/s/catalog/legacy/cluster_client_internal.cpp +++ b/src/mongo/s/catalog/legacy/cluster_client_internal.cpp @@ -44,188 +44,175 @@ namespace mongo { - using std::endl; - using std::string; - using std::unique_ptr; - using std::vector; - using mongoutils::str::stream; - - Status checkClusterMongoVersions(CatalogManager* catalogManager, - const string& minMongoVersion) { - - unique_ptr<ScopedDbConnection> connPtr; - - // - // Find mongos pings in config server - // - - try { - connPtr.reset(new ScopedDbConnection(catalogManager->connectionString(), 30)); - ScopedDbConnection& conn = *connPtr; - unique_ptr<DBClientCursor> cursor(_safeCursor(conn->query(MongosType::ConfigNS, - Query()))); - - while (cursor->more()) { - - BSONObj pingDoc = cursor->next(); - - MongosType ping; - string errMsg; - // NOTE: We don't care if the ping is invalid, legacy stuff will be - if (!ping.parseBSON(pingDoc, &errMsg)) { - warning() << "could not parse ping document: " << pingDoc << causedBy(errMsg) - << endl; - continue; - } +using std::endl; +using std::string; +using std::unique_ptr; +using std::vector; +using mongoutils::str::stream; + +Status checkClusterMongoVersions(CatalogManager* catalogManager, const string& minMongoVersion) { + unique_ptr<ScopedDbConnection> connPtr; + + // + // Find mongos pings in config server + // + + try { + connPtr.reset(new ScopedDbConnection(catalogManager->connectionString(), 30)); + ScopedDbConnection& conn = *connPtr; + unique_ptr<DBClientCursor> cursor(_safeCursor(conn->query(MongosType::ConfigNS, Query()))); + + while (cursor->more()) { + BSONObj pingDoc = cursor->next(); + + MongosType ping; + string errMsg; + // NOTE: We don't care if the ping is invalid, legacy stuff will be + if (!ping.parseBSON(pingDoc, &errMsg)) { + warning() << "could not parse ping document: " << pingDoc << causedBy(errMsg) + << endl; + continue; + } - string mongoVersion = "2.0"; - // Hack to determine older mongos versions from ping format - if (ping.isWaitingSet()) mongoVersion = "2.2"; - if (ping.isMongoVersionSet() && ping.getMongoVersion() != "") { - mongoVersion = ping.getMongoVersion(); - } + string mongoVersion = "2.0"; + // Hack to determine older mongos versions from ping format + if (ping.isWaitingSet()) + mongoVersion = "2.2"; + if (ping.isMongoVersionSet() && ping.getMongoVersion() != "") { + mongoVersion = ping.getMongoVersion(); + } - Date_t lastPing = ping.getPing(); + Date_t lastPing = ping.getPing(); - Minutes quietIntervalMins{0}; - Date_t currentJsTime = jsTime(); - if (currentJsTime >= lastPing) { - quietIntervalMins = duration_cast<Minutes>(currentJsTime - lastPing); - } + Minutes quietIntervalMins{0}; + Date_t currentJsTime = jsTime(); + if (currentJsTime >= lastPing) { + quietIntervalMins = duration_cast<Minutes>(currentJsTime - lastPing); + } - // We assume that anything that hasn't pinged in 5 minutes is probably down - if (quietIntervalMins >= Minutes{5}) { - log() << "stale mongos detected " << quietIntervalMins.count() - << " minutes ago, network location is " << pingDoc["_id"].String() - << ", not checking version"; - } - else { - if (versionCmp(mongoVersion, minMongoVersion) < 0) { - return Status(ErrorCodes::RemoteValidationError, - stream() << "version " << mongoVersion - << " detected on mongos at " - << ping.getName() - << ", but version >= " << minMongoVersion - << " required; you must wait 5 minutes " - << "after shutting down a pre-" << minMongoVersion - << " mongos"); - } + // We assume that anything that hasn't pinged in 5 minutes is probably down + if (quietIntervalMins >= Minutes{5}) { + log() << "stale mongos detected " << quietIntervalMins.count() + << " minutes ago, network location is " << pingDoc["_id"].String() + << ", not checking version"; + } else { + if (versionCmp(mongoVersion, minMongoVersion) < 0) { + return Status( + ErrorCodes::RemoteValidationError, + stream() << "version " << mongoVersion << " detected on mongos at " + << ping.getName() << ", but version >= " << minMongoVersion + << " required; you must wait 5 minutes " + << "after shutting down a pre-" << minMongoVersion << " mongos"); } } } - catch (const DBException& e) { - return e.toStatus("could not read mongos pings collection"); - } + } catch (const DBException& e) { + return e.toStatus("could not read mongos pings collection"); + } - connPtr->done(); + connPtr->done(); - // - // Load shards from config server - // + // + // Load shards from config server + // - vector<HostAndPort> servers; + vector<HostAndPort> servers; - try { - vector<ShardType> shards; - Status status = catalogManager->getAllShards(&shards); + try { + vector<ShardType> shards; + Status status = catalogManager->getAllShards(&shards); + if (!status.isOK()) { + return status; + } + + for (const ShardType& shard : shards) { + Status status = shard.validate(); if (!status.isOK()) { - return status; + return Status(ErrorCodes::UnsupportedFormat, + stream() << "shard " << shard.toBSON() + << " failed validation: " << causedBy(status)); } - for (const ShardType& shard : shards) { - Status status = shard.validate(); - if (!status.isOK()) { - return Status(ErrorCodes::UnsupportedFormat, - stream() << "shard " << shard.toBSON() - << " failed validation: " << causedBy(status)); - } - - const auto shardConnStatus = ConnectionString::parse(shard.getHost()); - if (!shardConnStatus.isOK()) { - return Status(ErrorCodes::UnsupportedFormat, - stream() << "invalid shard host " << shard.getHost() - << " read from the config server" - << shardConnStatus.getStatus().toString()); - } - - vector<HostAndPort> shardServers = shardConnStatus.getValue().getServers(); - servers.insert(servers.end(), shardServers.begin(), shardServers.end()); + const auto shardConnStatus = ConnectionString::parse(shard.getHost()); + if (!shardConnStatus.isOK()) { + return Status(ErrorCodes::UnsupportedFormat, + stream() << "invalid shard host " << shard.getHost() + << " read from the config server" + << shardConnStatus.getStatus().toString()); } - } - catch (const DBException& e) { - return e.toStatus("could not read shards collection"); - } - - // Add config servers to list of servers to check version against - vector<HostAndPort> configServers = catalogManager->connectionString().getServers(); - servers.insert(servers.end(), configServers.begin(), configServers.end()); - // - // We've now got all the shard info from the config server, start contacting the shards - // and config servers and verifying their versions. - // + vector<HostAndPort> shardServers = shardConnStatus.getValue().getServers(); + servers.insert(servers.end(), shardServers.begin(), shardServers.end()); + } + } catch (const DBException& e) { + return e.toStatus("could not read shards collection"); + } - for (vector<HostAndPort>::iterator serverIt = servers.begin(); - serverIt != servers.end(); ++serverIt) { + // Add config servers to list of servers to check version against + vector<HostAndPort> configServers = catalogManager->connectionString().getServers(); + servers.insert(servers.end(), configServers.begin(), configServers.end()); - // Note: This will *always* be a single-host connection - ConnectionString serverLoc(*serverIt); - dassert(serverLoc.type() == ConnectionString::MASTER || - serverLoc.type() == ConnectionString::CUSTOM); // for dbtests + // + // We've now got all the shard info from the config server, start contacting the shards + // and config servers and verifying their versions. + // - log() << "checking that version of host " << serverLoc << " is compatible with " - << minMongoVersion << endl; + for (vector<HostAndPort>::iterator serverIt = servers.begin(); serverIt != servers.end(); + ++serverIt) { + // Note: This will *always* be a single-host connection + ConnectionString serverLoc(*serverIt); + dassert(serverLoc.type() == ConnectionString::MASTER || + serverLoc.type() == ConnectionString::CUSTOM); // for dbtests - unique_ptr<ScopedDbConnection> serverConnPtr; + log() << "checking that version of host " << serverLoc << " is compatible with " + << minMongoVersion << endl; - bool resultOk; - BSONObj buildInfo; + unique_ptr<ScopedDbConnection> serverConnPtr; - try { - serverConnPtr.reset(new ScopedDbConnection(serverLoc, 30)); - ScopedDbConnection& serverConn = *serverConnPtr; + bool resultOk; + BSONObj buildInfo; - resultOk = serverConn->runCommand("admin", - BSON("buildInfo" << 1), - buildInfo); - } - catch (const DBException& e) { - warning() << "could not run buildInfo command on " << serverLoc.toString() << " " - << causedBy(e) << ". Please ensure that this server is up and at a " - "version >= " - << minMongoVersion; - continue; - } + try { + serverConnPtr.reset(new ScopedDbConnection(serverLoc, 30)); + ScopedDbConnection& serverConn = *serverConnPtr; + + resultOk = serverConn->runCommand("admin", BSON("buildInfo" << 1), buildInfo); + } catch (const DBException& e) { + warning() << "could not run buildInfo command on " << serverLoc.toString() << " " + << causedBy(e) << ". Please ensure that this server is up and at a " + "version >= " << minMongoVersion; + continue; + } - // TODO: Make running commands saner such that we can consolidate error handling - if (!resultOk) { - return Status(ErrorCodes::UnknownError, - stream() << DBClientConnection::getLastErrorString(buildInfo) - << causedBy(buildInfo.toString())); - } + // TODO: Make running commands saner such that we can consolidate error handling + if (!resultOk) { + return Status(ErrorCodes::UnknownError, + stream() << DBClientConnection::getLastErrorString(buildInfo) + << causedBy(buildInfo.toString())); + } - serverConnPtr->done(); + serverConnPtr->done(); - verify(buildInfo["version"].type() == String); - string mongoVersion = buildInfo["version"].String(); + verify(buildInfo["version"].type() == String); + string mongoVersion = buildInfo["version"].String(); - if (versionCmp(mongoVersion, minMongoVersion) < 0) { - return Status(ErrorCodes::RemoteValidationError, - stream() << "version " << mongoVersion << " detected on mongo " - "server at " << serverLoc.toString() << - ", but version >= " << minMongoVersion << " required"); - } + if (versionCmp(mongoVersion, minMongoVersion) < 0) { + return Status(ErrorCodes::RemoteValidationError, + stream() << "version " << mongoVersion << " detected on mongo " + "server at " + << serverLoc.toString() << ", but version >= " << minMongoVersion + << " required"); } - - return Status::OK(); } - // Helper function for safe cursors - DBClientCursor* _safeCursor(unique_ptr<DBClientCursor> cursor) { - // TODO: Make error handling more consistent, it's annoying that cursors error out by - // throwing exceptions *and* being empty - uassert(16625, str::stream() << "cursor not found, transport error", cursor.get()); - return cursor.release(); - } + return Status::OK(); +} +// Helper function for safe cursors +DBClientCursor* _safeCursor(unique_ptr<DBClientCursor> cursor) { + // TODO: Make error handling more consistent, it's annoying that cursors error out by + // throwing exceptions *and* being empty + uassert(16625, str::stream() << "cursor not found, transport error", cursor.get()); + return cursor.release(); +} } |