Merge branch 'master' of github.com:yandex/ClickHouse

This commit is contained in:
Alexey Milovidov 2017-09-07 20:56:04 +03:00
commit d3958c1802
8 changed files with 25 additions and 24 deletions

View File

@ -9,9 +9,8 @@
namespace DB
{
bool isLocalAddress(const Poco::Net::SocketAddress & address)
bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port)
{
const UInt16 clickhouse_port = Poco::Util::Application::instance().config().getInt("tcp_port", 0);
static auto interfaces = Poco::Net::NetworkInterface::list();
if (clickhouse_port == address.port())

View File

@ -20,6 +20,6 @@ namespace DB
* - only the first address is taken for each network interface;
* - the routing rules that affect which network interface we go to the specified address are not checked.
*/
bool isLocalAddress(const Poco::Net::SocketAddress & address);
bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port);
}

View File

@ -45,7 +45,7 @@ ClickHouseDictionarySource::ClickHouseDictionarySource(
where{config.getString(config_prefix + ".where", "")},
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::Backticks},
sample_block{sample_block}, context(context),
is_local{isLocalAddress({ host, port })},
is_local{isLocalAddress({ host, port }, config.getInt("tcp_port", 0))},
pool{is_local ? nullptr : createPool(host, port, db, user, password)},
load_all_query{query_builder.composeLoadAllQuery()}
{}

View File

@ -1709,7 +1709,7 @@ void FunctionHasColumnInTable::executeImpl(Block & block, const ColumnNumbers &
else
{
std::vector<std::vector<String>> host_names = {{ host_name }};
auto cluster = std::make_shared<Cluster>(global_context.getSettings(), host_names, !user_name.empty() ? user_name : "default", password);
auto cluster = std::make_shared<Cluster>(global_context.getSettings(), host_names, !user_name.empty() ? user_name : "default", password, global_context.getTCPPort());
auto names_and_types_list = std::make_shared<NamesAndTypesList>(getStructureOfRemoteTable(*cluster, database_name, table_name, global_context));
const auto & names = names_and_types_list->getNames();
has_column = std::find(names.begin(), names.end(), column_name) != names.end();

View File

@ -29,7 +29,7 @@ namespace
/// Default shard weight.
static constexpr UInt32 default_weight = 1;
inline bool isLocal(const Cluster::Address & address)
inline bool isLocal(const Cluster::Address & address, UInt16 clickhouse_port)
{
/// If there is replica, for which:
/// - its port is the same that the server is listening;
@ -41,7 +41,7 @@ inline bool isLocal(const Cluster::Address & address)
/// Also, replica is considered non-local, if it has default database set
/// (only reason is to avoid query rewrite).
return address.default_database.empty() && isLocalAddress(address.resolved_address);
return address.default_database.empty() && isLocalAddress(address.resolved_address, clickhouse_port);
}
@ -61,23 +61,23 @@ Poco::Net::SocketAddress resolveSocketAddress(const String & host_and_port)
Cluster::Address::Address(Poco::Util::AbstractConfiguration & config, const String & config_prefix)
{
UInt16 clickhouse_port = config.getInt("tcp_port", 0);
host_name = config.getString(config_prefix + ".host");
port = static_cast<UInt16>(config.getInt(config_prefix + ".port"));
resolved_address = resolveSocketAddress(host_name, port);
user = config.getString(config_prefix + ".user", "default");
password = config.getString(config_prefix + ".password", "");
default_database = config.getString(config_prefix + ".default_database", "");
is_local = isLocal(*this);
is_local = isLocal(*this, clickhouse_port);
}
Cluster::Address::Address(const String & host_port_, const String & user_, const String & password_)
Cluster::Address::Address(const String & host_port_, const String & user_, const String & password_, UInt16 clickhouse_port)
: user(user_), password(password_)
{
UInt16 default_port = static_cast<UInt16>(Poco::Util::Application::instance().config().getInt("tcp_port", 0));
/// It's like that 'host_port_' string contains port. If condition is met, it doesn't necessarily mean that port exists (example: [::]).
if ((nullptr != strchr(host_port_.c_str(), ':')) || !default_port)
if ((nullptr != strchr(host_port_.c_str(), ':')) || !clickhouse_port)
{
resolved_address = resolveSocketAddress(host_port_);
host_name = host_port_.substr(0, host_port_.find(':'));
@ -85,11 +85,11 @@ Cluster::Address::Address(const String & host_port_, const String & user_, const
}
else
{
resolved_address = resolveSocketAddress(host_port_, default_port);
resolved_address = resolveSocketAddress(host_port_, clickhouse_port);
host_name = host_port_;
port = default_port;
port = clickhouse_port;
}
is_local = isLocal(*this);
is_local = isLocal(*this, clickhouse_port);
}
@ -333,7 +333,7 @@ Cluster::Cluster(Poco::Util::AbstractConfiguration & config, const Settings & se
Cluster::Cluster(const Settings & settings, const std::vector<std::vector<String>> & names,
const String & username, const String & password)
const String & username, const String & password, UInt16 clickhouse_port)
{
UInt32 current_shard_num = 1;
@ -341,7 +341,7 @@ Cluster::Cluster(const Settings & settings, const std::vector<std::vector<String
{
Addresses current;
for (auto & replica : shard)
current.emplace_back(replica, username, password);
current.emplace_back(replica, username, password, clickhouse_port);
addresses_with_failover.emplace_back(current);

View File

@ -19,8 +19,10 @@ public:
Cluster(Poco::Util::AbstractConfiguration & config, const Settings & settings, const String & cluster_name);
/// Construct a cluster by the names of shards and replicas. Local are treated as well as remote ones.
/// 'clickhouse_port' - port that this server instance listen for queries.
/// This parameter is needed only to check that some address is local (points to ourself).
Cluster(const Settings & settings, const std::vector<std::vector<String>> & names,
const String & username, const String & password);
const String & username, const String & password, UInt16 clickhouse_port);
Cluster(const Cluster &) = delete;
Cluster & operator=(const Cluster &) = delete;
@ -59,7 +61,7 @@ public:
Address() = default;
Address(Poco::Util::AbstractConfiguration & config, const String & config_prefix);
Address(const String & host_port_, const String & user_, const String & password_);
Address(const String & host_port_, const String & user_, const String & password_, UInt16 clickhouse_port);
/// Returns 'escaped_host_name:port'
String toString() const;

View File

@ -82,11 +82,11 @@ struct HostID
return host_name + ":" + DB::toString(port);
}
bool isLocalAddress() const
bool isLocalAddress(UInt16 clickhouse_port) const
{
try
{
return DB::isLocalAddress(Poco::Net::SocketAddress(DNSCache::instance().resolveHost(host_name), port));
return DB::isLocalAddress(Poco::Net::SocketAddress(host_name, port), clickhouse_port);
}
catch (const Poco::Exception & e)
{
@ -287,7 +287,7 @@ bool DDLWorker::initAndCheckTask(const String & entry_name, String & out_reason)
bool host_in_hostlist = false;
for (const HostID & host : task->entry.hosts)
{
if (!host.isLocalAddress())
if (!host.isLocalAddress(context.getTCPPort()))
continue;
if (host_in_hostlist)
@ -464,7 +464,7 @@ void DDLWorker::parseQueryAndResolveHost(DDLTask & task)
{
const Cluster::Address & address = shards[shard_num][replica_num];
if (isLocalAddress(address.resolved_address))
if (isLocalAddress(address.resolved_address, context.getTCPPort()))
{
if (found_via_resolving)
{

View File

@ -274,7 +274,7 @@ StoragePtr TableFunctionRemote::execute(const ASTPtr & ast_function, const Conte
if (names.empty())
throw Exception("Shard list is empty after parsing first argument", ErrorCodes::BAD_ARGUMENTS);
auto cluster = std::make_shared<Cluster>(context.getSettings(), names, username, password);
auto cluster = std::make_shared<Cluster>(context.getSettings(), names, username, password, context.getTCPPort());
auto res = StorageDistributed::createWithOwnCluster(
getName(),