dbms: fixed error [#METR-16575] [#METR-16573].

This commit is contained in:
Alexey Milovidov 2015-05-29 03:33:56 +03:00
parent 3786513a3c
commit 3db1bf63a2
9 changed files with 92 additions and 30 deletions

View File

@ -67,6 +67,8 @@ public:
if (user.empty())
user = "default";
setDescription();
}
Connection(const String & host_, UInt16 port_, const Poco::Net::SocketAddress & resolved_address_,
@ -93,6 +95,8 @@ public:
if (user.empty())
user = "default";
setDescription();
}
virtual ~Connection() {};
@ -122,8 +126,11 @@ public:
void getServerVersion(String & name, UInt64 & version_major, UInt64 & version_minor, UInt64 & revision);
/// Адрес сервера - для сообщений в логе и в эксепшенах.
String getServerAddress() const;
/// Для сообщений в логе и в эксепшенах.
const String & getDescription() const
{
return description;
}
const String & getHost() const
{
@ -177,9 +184,15 @@ private:
String user;
String password;
/// Адрес может быть заранее отрезолвен и передан в конструктор. Тогда поля host и port имеют смысл только для логгирования.
/** Адрес может быть заранее отрезолвен и передан в конструктор. Тогда поля host и port имеют смысл только для логгирования.
* Иначе адрес резолвится в конструкторе. То есть, DNS балансировка не поддерживается.
*/
Poco::Net::SocketAddress resolved_address;
/// Для сообщений в логе и в эксепшенах.
String description;
void setDescription();
String client_name;
bool connected = false;
@ -228,7 +241,7 @@ private:
Logger * get()
{
if (!log)
log = &Logger::get("Connection (" + parent.getServerAddress() + ")");
log = &Logger::get("Connection (" + parent.getDescription() + ")");
return log;
}

View File

@ -107,7 +107,8 @@ protected:
ConnectionPtr allocObject() override
{
return new Connection(
host, port, default_database, user, password,
host, port, resolved_address,
default_database, user, password,
client_name, compression,
connect_timeout, receive_timeout, send_timeout);
}
@ -119,7 +120,9 @@ private:
String user;
String password;
/// Адрес может быть заранее отрезолвен и передан в конструктор. Тогда поля host и port имеют смысл только для логгирования.
/** Адрес может быть заранее отрезолвен и передан в конструктор. Тогда поля host и port имеют смысл только для логгирования.
* Иначе адрес резолвится в конструкторе. То есть, DNS балансировка не поддерживается.
*/
Poco::Net::SocketAddress resolved_address;
String client_name;

View File

@ -5,6 +5,7 @@
#include <statdaemons/PoolWithFailoverBase.h>
#include <DB/Common/getFQDNOrHostName.h>
#include <DB/Client/ConnectionPool.h>
@ -33,7 +34,7 @@ public:
: Base(nested_pools_, max_tries_, decrease_error_period_,
&Logger::get("ConnectionPoolWithFailover")), default_load_balancing(load_balancing)
{
std::string local_hostname = Poco::Net::DNS::hostName();
const std::string & local_hostname = getFQDNOrHostName();
hostname_differences.resize(nested_pools.size());
for (size_t i = 0; i < nested_pools.size(); ++i)

View File

@ -0,0 +1,8 @@
#pragma once
#include <string>
/** Получить FQDN для локального сервера путём DNS-резолвинга hostname - аналогично вызову утилиты hostname с флагом -f.
* Если не получилось отрезолвить, то вернуть hostname - аналогично вызову утилиты hostname без флагов или uname -n.
*/
const std::string & getFQDNOrHostName();

View File

@ -112,6 +112,7 @@ public:
}
};
/// Получить имя хоста. (Оно - константа, вычисляется один раз за весь запрос.)
class FunctionHostName : public IFunction
{
@ -146,6 +147,7 @@ public:
}
};
class FunctionVisibleWidth : public IFunction
{
public:

View File

@ -34,7 +34,7 @@ void Connection::connect()
if (connected)
disconnect();
LOG_TRACE(log_wrapper.get(), "Connecting. Database: " << default_database << ". User: " << user);
LOG_TRACE(log_wrapper.get(), "Connecting. Database: " << (default_database.empty() ? "(not specified)" : default_database) << ". User: " << user);
socket.connect(resolved_address, connect_timeout);
socket.setReceiveTimeout(receive_timeout);
@ -60,21 +60,21 @@ void Connection::connect()
disconnect();
/// Добавляем в сообщение адрес сервера. Также объект Exception запомнит stack trace. Жаль, что более точный тип исключения теряется.
throw NetException(e.displayText(), "(" + getServerAddress() + ")", ErrorCodes::NETWORK_ERROR);
throw NetException(e.displayText(), "(" + getDescription() + ")", ErrorCodes::NETWORK_ERROR);
}
catch (Poco::TimeoutException & e)
{
disconnect();
/// Добавляем в сообщение адрес сервера. Также объект Exception запомнит stack trace. Жаль, что более точный тип исключения теряется.
throw NetException(e.displayText(), "(" + getServerAddress() + ")", ErrorCodes::SOCKET_TIMEOUT);
throw NetException(e.displayText(), "(" + getDescription() + ")", ErrorCodes::SOCKET_TIMEOUT);
}
}
void Connection::disconnect()
{
//LOG_TRACE(log_wrapper.get(), "Disconnecting (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Disconnecting");
socket.close();
in = nullptr;
@ -85,7 +85,7 @@ void Connection::disconnect()
void Connection::sendHello()
{
//LOG_TRACE(log_wrapper.get(), "Sending hello (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Sending hello");
writeVarUInt(Protocol::Client::Hello, *out);
writeStringBinary((DBMS_NAME " ") + client_name, *out);
@ -102,7 +102,7 @@ void Connection::sendHello()
void Connection::receiveHello()
{
//LOG_TRACE(log_wrapper.get(), "Receiving hello (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Receiving hello");
/// Получить hello пакет.
UInt64 packet_type = 0;
@ -127,7 +127,7 @@ void Connection::receiveHello()
/// Закроем соединение, чтобы не было рассинхронизации.
disconnect();
throw NetException("Unexpected packet from server " + getServerAddress() + " (expected Hello or Exception, got "
throw NetException("Unexpected packet from server " + getDescription() + " (expected Hello or Exception, got "
+ String(Protocol::Server::toString(packet_type)) + ")", ErrorCodes::UNEXPECTED_PACKET_FROM_SERVER);
}
}
@ -192,7 +192,7 @@ struct PingTimeoutSetter
bool Connection::ping()
{
// LOG_TRACE(log_wrapper.get(), "Ping (" << getServerAddress() << ")");
// LOG_TRACE(log_wrapper.get(), "Ping");
PingTimeoutSetter timeout_setter(socket, ping_timeout);
try
@ -219,7 +219,7 @@ bool Connection::ping()
if (pong != Protocol::Server::Pong)
{
throw Exception("Unexpected packet from server " + getServerAddress() + " (expected Pong, got "
throw Exception("Unexpected packet from server " + getDescription() + " (expected Pong, got "
+ String(Protocol::Server::toString(pong)) + ")",
ErrorCodes::UNEXPECTED_PACKET_FROM_SERVER);
}
@ -242,7 +242,7 @@ void Connection::sendQuery(const String & query, const String & query_id_, UInt6
query_id = query_id_;
//LOG_TRACE(log_wrapper.get(), "Sending query (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Sending query");
writeVarUInt(Protocol::Client::Query, *out);
@ -281,7 +281,7 @@ void Connection::sendQuery(const String & query, const String & query_id_, UInt6
void Connection::sendCancel()
{
//LOG_TRACE(log_wrapper.get(), "Sending cancel (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Sending cancel");
writeVarUInt(Protocol::Client::Cancel, *out);
out->next();
@ -290,7 +290,7 @@ void Connection::sendCancel()
void Connection::sendData(const Block & block, const String & name)
{
//LOG_TRACE(log_wrapper.get(), "Sending data (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Sending data");
if (!block_out)
{
@ -405,7 +405,7 @@ bool Connection::hasReadBufferPendingData() const
Connection::Packet Connection::receivePacket()
{
//LOG_TRACE(log_wrapper.get(), "Receiving packet (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Receiving packet");
try
{
@ -448,14 +448,14 @@ Connection::Packet Connection::receivePacket()
disconnect();
throw Exception("Unknown packet "
+ toString(res.type)
+ " from server " + getServerAddress(), ErrorCodes::UNKNOWN_PACKET_FROM_SERVER);
+ " from server " + getDescription(), ErrorCodes::UNKNOWN_PACKET_FROM_SERVER);
}
}
catch (Exception & e)
{
/// Дописываем в текст исключения адрес сервера, если надо.
if (e.code() != ErrorCodes::UNKNOWN_PACKET_FROM_SERVER)
e.addMessage("while receiving packet from " + getServerAddress());
e.addMessage("while receiving packet from " + getDescription());
throw;
}
@ -464,7 +464,7 @@ Connection::Packet Connection::receivePacket()
Block Connection::receiveData()
{
//LOG_TRACE(log_wrapper.get(), "Receiving data (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Receiving data");
initBlockInput();
@ -499,25 +499,29 @@ void Connection::initBlockInput()
}
String Connection::getServerAddress() const
void Connection::setDescription()
{
return host + ":" + toString(resolved_address.port()) + ", " + resolved_address.host().toString();
description = host + ":" + toString(resolved_address.port());
auto ip_address = resolved_address.host().toString();
if (host != ip_address)
description += ", " + ip_address;
}
SharedPtr<Exception> Connection::receiveException()
{
//LOG_TRACE(log_wrapper.get(), "Receiving exception (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Receiving exception");
Exception e;
readException(e, *in, "Received from " + getServerAddress());
readException(e, *in, "Received from " + getDescription());
return e.clone();
}
Progress Connection::receiveProgress()
{
//LOG_TRACE(log_wrapper.get(), "Receiving progress (" << getServerAddress() << ")");
//LOG_TRACE(log_wrapper.get(), "Receiving progress");
Progress progress;
progress.read(*in, server_revision);

View File

@ -184,7 +184,7 @@ std::string ParallelReplicas::dumpAddresses() const
const Connection * connection = e.second;
if (connection != nullptr)
{
os << (is_first ? "" : "; ") << connection->getServerAddress();
os << (is_first ? "" : "; ") << connection->getDescription();
is_first = false;
}
}

View File

@ -0,0 +1,25 @@
#include <Poco/Net/DNS.h>
#include <DB/Common/getFQDNOrHostName.h>
namespace
{
std::string getFQDNOrHostNameImpl()
{
try
{
return Poco::Net::DNS::thisHost().name();
}
catch (...)
{
return Poco::Net::DNS::hostName();
}
}
}
const std::string & getFQDNOrHostName()
{
static std::string result = getFQDNOrHostNameImpl();
return result;
}

View File

@ -18,6 +18,7 @@
#include <condition_variable>
#include <DB/Common/Macros.h>
#include <DB/Common/getFQDNOrHostName.h>
#include <DB/Interpreters/loadMetadata.h>
#include <DB/Storages/StorageSystemNumbers.h>
#include <DB/Storages/StorageSystemTables.h>
@ -485,9 +486,14 @@ int Server::main(const std::vector<std::string> & args)
{
String this_host;
if (config().has("interserver_http_host"))
{
this_host = config().getString("interserver_http_host");
}
else
this_host = Poco::Net::DNS::hostName();
{
this_host = getFQDNOrHostName();
LOG_DEBUG(log, "Configuration parameter 'interserver_http_host' doesn't exist. Will use '" + this_host + "' as replica host.");
}
String port_str = config().getString("interserver_http_port");
int port = parse<int>(port_str);