void ShardRegistry::_addShard_inlock(const ShardType& shardType) { // This validation should ideally go inside the ShardType::validate call. However, doing // it there would prevent us from loading previously faulty shard hosts, which might have // been stored (i.e., the entire getAllShards call would fail). auto shardHostStatus = ConnectionString::parse(shardType.getHost()); if (!shardHostStatus.isOK()) { warning() << "Unable to parse shard host " << shardHostStatus.getStatus().toString(); } const ConnectionString& shardHost(shardHostStatus.getValue()); shared_ptr<Shard> shard; if (shardHost.type() == ConnectionString::SYNC) { // Sync cluster connections (legacy config server) do not go through the normal targeting // mechanism and must only be reachable through CatalogManagerLegacy or legacy-style queries // and inserts. Do not create targeter for these connections. This code should go away after // 3.2 is released. shard = std::make_shared<Shard>(shardType.getName(), shardHost, nullptr); } else { // Non-SYNC shards use targeter factory. shard = std::make_shared<Shard>( shardType.getName(), shardHost, _targeterFactory->create(shardHost)); } _updateLookupMapsForShard_inlock(std::move(shard), shardHost); }
void ShardRegistry::_addShard_inlock(const ShardType& shardType) { // This validation should ideally go inside the ShardType::validate call. However, doing // it there would prevent us from loading previously faulty shard hosts, which might have // been stored (i.e., the entire getAllShards call would fail). auto shardHostStatus = ConnectionString::parse(shardType.getHost()); if (!shardHostStatus.isOK()) { warning() << "Unable to parse shard host " << shardHostStatus.getStatus().toString(); } const ConnectionString& shardHost(shardHostStatus.getValue()); shared_ptr<Shard> shard = boost::make_shared<Shard>(shardType.getName(), shardHost, shardType.getMaxSize(), shardType.getDraining()); _lookup[shardType.getName()] = shard; _lookup[shardType.getHost()] = shard; if (shardHost.type() == ConnectionString::SET) { if (shardHost.getSetName().size()) { _rsLookup[shardHost.getSetName()] = shard; } vector<HostAndPort> servers = shardHost.getServers(); for (unsigned i = 0; i < servers.size(); i++) { _lookup[servers[i].toString()] = shard; } } }
void ShardRegistry::_addShard_inlock(const ShardType& shardType) { // This validation should ideally go inside the ShardType::validate call. However, doing // it there would prevent us from loading previously faulty shard hosts, which might have // been stored (i.e., the entire getAllShards call would fail). auto shardHostStatus = ConnectionString::parse(shardType.getHost()); if (!shardHostStatus.isOK()) { warning() << "Unable to parse shard host " << shardHostStatus.getStatus().toString(); } const ConnectionString& shardHost(shardHostStatus.getValue()); // Sync cluster connections (legacy config server) do not go through the normal targeting // mechanism and must only be reachable through CatalogManagerLegacy or legacy-style // queries and inserts. Do not create targeter for these connections. This code should go // away after 3.2 is released. if (shardHost.type() == ConnectionString::SYNC) { _lookup[shardType.getName()] = std::make_shared<Shard>(shardType.getName(), shardHost, nullptr); return; } // Non-SYNC shards shared_ptr<Shard> shard = std::make_shared<Shard>( shardType.getName(), shardHost, std::move(_targeterFactory->create(shardHost))); _lookup[shardType.getName()] = shard; // TODO: The only reason to have the shard host names in the lookup table is for the // setShardVersion call, which resolves the shard id from the shard address. This is // error-prone and will go away eventually when we switch all communications to go through // the remote command runner. _lookup[shardType.getHost()] = shard; for (const HostAndPort& hostAndPort : shardHost.getServers()) { _lookup[hostAndPort.toString()] = shard; // Maintain a mapping from host to shard it belongs to for the case where we need to // update the shard connection string on reconfigurations. if (shardHost.type() == ConnectionString::SET) { _rsLookup[hostAndPort.toString()] = shard; } } if (shardHost.type() == ConnectionString::SET) { _rsLookup[shardHost.getSetName()] = shard; } }
TEST_F(EnableShardingTest, succeedsWhenTheDatabaseIsAlreadySharded) { ShardType shard; shard.setName("shard0"); shard.setHost("shard0:12"); ASSERT_OK(setupShards(vector<ShardType>{shard})); setupDatabase("db5", shard.getName(), true); auto status = ShardingCatalogManager::get(operationContext())->enableSharding(operationContext(), "db5"); ASSERT_OK(status); }