mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
dbms: Server: queries with several replicas: fixes [#METR-14410]
This commit is contained in:
parent
2e5d1041a1
commit
8c0a540350
@ -29,9 +29,6 @@ namespace DB
|
|||||||
/// Получить пакет от какой-нибудь реплики.
|
/// Получить пакет от какой-нибудь реплики.
|
||||||
Connection::Packet receivePacket();
|
Connection::Packet receivePacket();
|
||||||
|
|
||||||
/// Разорвать соединения к репликам
|
|
||||||
void disconnect();
|
|
||||||
|
|
||||||
/// Отменить запросы к репликам
|
/// Отменить запросы к репликам
|
||||||
void sendCancel();
|
void sendCancel();
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ public:
|
|||||||
if (!__sync_bool_compare_and_swap(&is_cancelled, false, true))
|
if (!__sync_bool_compare_and_swap(&is_cancelled, false, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sent_query && !was_cancelled && !finished && !got_exception_from_replica)
|
if (isInProgress() && !hasThrownException() && !was_cancelled)
|
||||||
{
|
{
|
||||||
std::string addresses = parallel_replicas->dumpAddresses();
|
std::string addresses = parallel_replicas->dumpAddresses();
|
||||||
LOG_TRACE(log, "(" + addresses + ") Cancelling query");
|
LOG_TRACE(log, "(" + addresses + ") Cancelling query");
|
||||||
@ -96,11 +96,12 @@ public:
|
|||||||
|
|
||||||
~RemoteBlockInputStream() override
|
~RemoteBlockInputStream() override
|
||||||
{
|
{
|
||||||
/** Если прервались в середине цикла общения с репликами, то закрываем соединения,
|
/** Если прервались в середине цикла общения с репликами, то прервываем
|
||||||
* чтобы они не остались висеть в рассихронизированном состоянии.
|
* все соединения, затем читаем и пропускаем оставшиеся пакеты чтобы
|
||||||
|
* эти соединения не остались висеть в рассихронизированном состоянии.
|
||||||
*/
|
*/
|
||||||
if (sent_query && !finished)
|
if (isInProgress())
|
||||||
parallel_replicas->disconnect();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -156,7 +157,6 @@ protected:
|
|||||||
|
|
||||||
case Protocol::Server::Exception:
|
case Protocol::Server::Exception:
|
||||||
got_exception_from_replica = true;
|
got_exception_from_replica = true;
|
||||||
abort();
|
|
||||||
packet.exception->rethrow();
|
packet.exception->rethrow();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ protected:
|
|||||||
*/
|
*/
|
||||||
progressImpl(packet.progress);
|
progressImpl(packet.progress);
|
||||||
|
|
||||||
if (!was_cancelled && !finished && isCancelled())
|
if (!was_cancelled && isInProgress() && isCancelled())
|
||||||
cancel();
|
cancel();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -196,7 +196,6 @@ protected:
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
got_unknown_packet_from_replica = true;
|
got_unknown_packet_from_replica = true;
|
||||||
abort();
|
|
||||||
throw Exception("Unknown packet from server", ErrorCodes::UNKNOWN_PACKET_FROM_SERVER);
|
throw Exception("Unknown packet from server", ErrorCodes::UNKNOWN_PACKET_FROM_SERVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,10 +206,11 @@ protected:
|
|||||||
/** Если одно из:
|
/** Если одно из:
|
||||||
* - ничего не начинали делать;
|
* - ничего не начинали делать;
|
||||||
* - получили все пакеты до EndOfStream;
|
* - получили все пакеты до EndOfStream;
|
||||||
* - получили с сервера эксепшен;
|
* - получили с одной реплики эксепшен;
|
||||||
|
* - получили с одной реплики неизвестный пакет;
|
||||||
* - то больше читать ничего не нужно.
|
* - то больше читать ничего не нужно.
|
||||||
*/
|
*/
|
||||||
if (!sent_query || finished || got_exception_from_replica)
|
if (!isInProgress() || hasThrownException())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/** Если ещё прочитали не все данные, но они больше не нужны.
|
/** Если ещё прочитали не все данные, но они больше не нужны.
|
||||||
@ -256,13 +256,10 @@ protected:
|
|||||||
parallel_replicas = ext::make_unique<ParallelReplicas>(pool, parallel_replicas_settings);
|
parallel_replicas = ext::make_unique<ParallelReplicas>(pool, parallel_replicas_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Если с одной реплики был получен пакет Exception или неизвестный пакет, отменить запросы на всех
|
/** Отменить запросы на всех репликах. Читать и пропускать все оставшиеся пакеты
|
||||||
* остальных репликах. Читать и пропускать все оставшиеся пакеты до EndOfStream или Exception, чтобы
|
* до EndOfStream или Exception, чтоб не было рассинхронизации в соединениях с репликами.
|
||||||
* не было рассинхронизации в соединениях с репликами.
|
|
||||||
*/
|
*/
|
||||||
void abort()
|
void abort()
|
||||||
{
|
|
||||||
if (got_exception_from_replica || got_unknown_packet_from_replica)
|
|
||||||
{
|
{
|
||||||
std::string addresses = parallel_replicas->dumpAddresses();
|
std::string addresses = parallel_replicas->dumpAddresses();
|
||||||
LOG_TRACE(log, "(" + addresses + ") Aborting query");
|
LOG_TRACE(log, "(" + addresses + ") Aborting query");
|
||||||
@ -270,6 +267,17 @@ protected:
|
|||||||
parallel_replicas->sendCancel();
|
parallel_replicas->sendCancel();
|
||||||
(void) parallel_replicas->drain();
|
(void) parallel_replicas->drain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Возвращает true, если запрос отправлен, а ещё не выполнен.
|
||||||
|
bool isInProgress() const
|
||||||
|
{
|
||||||
|
return sent_query && !finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Возвращает true, если исключение было выкинуто.
|
||||||
|
bool hasThrownException() const
|
||||||
|
{
|
||||||
|
return got_exception_from_replica || got_unknown_packet_from_replica;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -133,19 +133,6 @@ namespace DB
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelReplicas::disconnect()
|
|
||||||
{
|
|
||||||
for (auto it = replica_map.begin(); it != replica_map.end(); ++it)
|
|
||||||
{
|
|
||||||
Connection * connection = it->second;
|
|
||||||
if (connection != nullptr)
|
|
||||||
{
|
|
||||||
connection->disconnect();
|
|
||||||
invalidateReplica(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ParallelReplicas::sendCancel()
|
void ParallelReplicas::sendCancel()
|
||||||
{
|
{
|
||||||
if (!sent_query || cancelled)
|
if (!sent_query || cancelled)
|
||||||
|
Loading…
Reference in New Issue
Block a user