Обзор
Фоновые запросы позволяют клиентам отправлять запросы, которые выполняются независимо от клиентского сеанса — для этого нужно задатьrun_query_in_background=1. Сразу после отправки ClickHouse server отвечает клиенту, а запрос при этом продолжает выполняться на стороне сервера до завершения (успешного или с ошибкой).
Поскольку выполнение запроса не привязано к сетевому соединению клиента, фоновые задачи полностью устойчивы к разрывам соединения на стороне клиента и кратковременным сетевым сбоям.
Фоновые запросы в первую очередь предназначены для длительных операций, таких как INSERT ... SELECT,
CREATE TABLE ... AS SELECT, CREATE MATERIALIZED VIEW ... POPULATE или OPTIMIZE TABLE ... FINAL,
которые не должны прерываться при разрыве клиентского соединения.
Не каждый запрос можно отвязать от соединения. Список запросов, которые вместо этого отклоняются, см. в разделе Неподдерживаемые формы запросов.
Фоновый запрос не переживает перезапуск сервера. Поведение при остановке сервера определяется параметрами
shutdown_wait_unfinished_queries и shutdown_wait_unfinished.
Неподдерживаемые формы запросов
Фоновый запрос живёт дольше, чем отправившее его соединение, поэтому уже в момент приёма запроса у сервера должно быть всё необходимое для его выполнения. Запросы, не удовлетворяющие этому условию, отклоняются синхронно — в том же соединении, из которого были отправлены, — и никогда не запускаются.Данные, передаваемые через соединение
INSERT отклоняется, если после отправки запроса на выполнение серверу всё ещё потребуется читать данные из соединения, по которому этот запрос пришёл.
Это может касаться как INSERT ... FORMAT ..., так и запросов, читающих данные через input. Такой запрос отклоняется с ошибкой A query whose data streams over the connection cannot be run in the background:
clickhouse-client отправляет данные INSERT ... FORMAT ... отдельными пакетами, поэтому такая форма в принципе не может выполняться в фоновом режиме через собственный протокол.
По HTTP допустима любая из форм, если запрос целиком вместе с данными помещается в начальный буфер разбора, размер которого ограничен параметром max_query_size.
Это относится и к HTTP-запросу, который читает встроенную полезную нагрузку через input. Более объёмное тело продолжает передаваться потоком за пределами буферизованного текста запроса и будет отклонено.
Не полагайтесь на это ограничение по размеру: для данных, которые должны загружаться в фоновом режиме, используйте INSERT ... SELECT либо табличную функцию, например url или s3.
Другие отклонённые запросы
Эта настройка никогда не распространяется на вторичные запросы распределённого запроса: фоновый распределённый
INSERT
выполняет свои запросы к отдельным сегментам не в фоне, а в рамках фонового исходного запроса.
Отправка фонового запроса
Собственный TCP-протокол
В клиенте ClickHouse передайтеrun_query_in_background как настройку командной строки:
SETTINGS:
clickhouse-client разбирает большинство настроек, указанных в самом запросе, и отправляет их в этой секции настроек.
Драйверы, работающие поверх собственного протокола, могут вместо этого передавать run_query_in_background в своём наборе настроек для отдельного запроса, оставляя текст SQL без изменений.
Собственный протокол не возвращает сгенерированный сервером query_id. Нативные клиенты должны сами сформировать уникальный ID и отправить его вместе с запросом.
clickhouse-client --echo-query-id делает это и выводит ID перед отправкой запроса:
HTTP-протокол
Для HTTP-запросов передавайтеrun_query_in_background в качестве URL-параметра:
X-ClickHouse-Query-Id:
query_id в качестве URL-параметра.
Тогда клиент знает ID ещё до отправки запроса и может отслеживать или завершить (KILL) запрос на принимающем узле, даже если так и не получит ответ:
SETTINGS:
BAD_ARGUMENTS. HTTP handler должен решить, создавать ли detached-контекст запроса, ещё до того, как будет разобрано тело запроса.
Передайте настройку в URL либо задайте её на уровне пользователя или профиля.
Мониторинг выполнения
Используйтеquery_id, чтобы проверить, выполняется ли запрос в данный момент:
system.query_log:
system.query_log, а не возвращается по исходному соединению.
system.processes, system.query_log и KILL QUERY работают локально на узле: каждый из них видит только запросы того сервера, который его обрабатывает.Фоновый запрос принадлежит серверу, который его принял, а это не обязательно тот сервер, на который попадет ваш следующий запрос через балансировщик нагрузки. Вместо этого читайте данные по всему кластеру:system.query_log, а для отмены требуется общекластерная форма:Задержка сброса журнала запросов
Записи буферизуются, прежде чем попасть вsystem.query_log.
В самоуправляемом ClickHouse в примере серверной конфигурации параметру query_log.flush_interval_milliseconds присвоено значение 7500.
В ClickHouse Cloud записи могут появляться с задержкой до 30 секунд. Учитывайте эту задержку при мониторинге кратковременных фоновых запросов.
На самоуправляемом сервере пользователи с достаточными привилегиями могут принудительно сбросить журнал запросов. Указывайте журнал явно, чтобы не затрагивать остальные системные журналы:
system.query_log другого сервера не становится доступен локально, поэтому лог по-прежнему следует читать через clusterAllReplicas, как описано в разделе Monitor execution.