Skip to main content

Обзор

Фоновые запросы позволяют клиентам отправлять запросы, которые выполняются независимо от клиентского сеанса — для этого нужно задать run_query_in_background=1. Сразу после отправки ClickHouse server отвечает клиенту, а запрос при этом продолжает выполняться на стороне сервера до завершения (успешного или с ошибкой). Поскольку выполнение запроса не привязано к сетевому соединению клиента, фоновые задачи полностью устойчивы к разрывам соединения на стороне клиента и кратковременным сетевым сбоям. Фоновые запросы в первую очередь предназначены для длительных операций, таких как INSERT ... SELECT, CREATE TABLE ... AS SELECT, CREATE MATERIALIZED VIEW ... POPULATE или OPTIMIZE TABLE ... FINAL, которые не должны прерываться при разрыве клиентского соединения. Не каждый запрос можно отвязать от соединения. Список запросов, которые вместо этого отклоняются, см. в разделе Неподдерживаемые формы запросов.
Результат фонового запроса отбрасывается. Получить его или подключиться к запросу позднее невозможно. Используйте query_id запроса, чтобы отслеживать его в system.processes во время выполнения и в system.query_log после завершения.
Фоновый запрос не переживает перезапуск сервера. Поведение при остановке сервера определяется параметрами 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:
Собственный протокол передаёт настройки запроса отдельно от текста SQL. 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) запрос на принимающем узле, даже если так и не получит ответ:
В отличие от собственного протокола, HTTP не позволяет включить фоновое выполнение с помощью встроенного в SQL-запрос предложения SETTINGS:
Такой запрос возвращает исключение BAD_ARGUMENTS. HTTP handler должен решить, создавать ли detached-контекст запроса, ещё до того, как будет разобрано тело запроса. Передайте настройку в URL либо задайте её на уровне пользователя или профиля.

Мониторинг выполнения

Используйте query_id, чтобы проверить, выполняется ли запрос в данный момент:
После завершения запроса проверьте его итоговый status в 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.
Последнее изменение 26 сентября 2026 г.