Skip to main content

Vue d’ensemble

Les requêtes en arrière-plan permettent aux clients de soumettre des requêtes qui s’exécutent indépendamment de la session client, en définissant run_query_in_background=1. Une fois la requête soumise, le ClickHouse server répond immédiatement au client, tandis que la requête poursuit son exécution jusqu’à son terme (succès ou échec) côté serveur En dissociant l’exécution de la requête de la connexion réseau du client, les tâches en arrière-plan sont pleinement résilientes aux déconnexions côté client et aux défaillances réseau passagères. Les requêtes en arrière-plan sont principalement destinées aux opérations de longue durée telles que INSERT ... SELECT, CREATE TABLE ... AS SELECT, CREATE MATERIALIZED VIEW ... POPULATE ou OPTIMIZE TABLE ... FINAL qui ne doivent pas s’interrompre en cas de perte de la connexion client. Toutes les requêtes ne peuvent pas être détachées de leur connexion. Consultez Formes de requêtes non prises en charge pour connaître celles qui sont rejetées.
Le résultat d’une requête en arrière-plan est abandonné : il ne peut être ni récupéré ni rattaché ultérieurement. Utilisez le query_id de la requête pour la surveiller dans system.processes pendant son exécution, puis dans system.query_log une fois celle-ci terminée.
Une requête en arrière-plan ne survit pas au redémarrage d’un serveur. Le comportement à l’arrêt du serveur est régi par shutdown_wait_unfinished_queries et shutdown_wait_unfinished.

Formes de requête non prises en charge

Une requête en arrière-plan survit à la connexion qui l’a soumise : le serveur doit donc déjà disposer, au moment où il l’accepte, de tout ce dont il a besoin pour l’exécuter. Les requêtes qui ne remplissent pas cette condition sont rejetées de manière synchrone, sur la connexion à l’origine de la soumission, et la requête ne démarre jamais.

Données transmises via la connexion

Un INSERT est rejeté lorsque le serveur devrait encore lire des données depuis la connexion émettrice après avoir distribué la requête. Cela peut concerner aussi bien les requêtes INSERT ... FORMAT ... que celles qui lisent via input. Une telle requête est rejetée avec le message A query whose data streams over the connection cannot be run in the background :
clickhouse-client envoie les données d’un INSERT ... FORMAT ... dans des paquets distincts ; cette forme ne peut donc jamais s’exécuter en arrière-plan via le protocole natif. En HTTP, l’une ou l’autre forme peut être acceptée lorsque la requête complète et ses données tiennent dans le buffer de parsing initial, dont la taille est limitée par max_query_size. Cela vaut également pour une requête HTTP qui lit un payload intégré via input. Un corps plus volumineux continue d’être transmis en flux au-delà du texte de requête mis en buffer et se voit rejeté. Ne vous fiez pas à cette limite de taille : utilisez INSERT ... SELECT, ou une fonction de table telle que url ou s3, pour les données qui doivent être chargées en arrière-plan.

Autres requêtes rejetées

Le paramètre n’est jamais propagé aux requêtes secondaires d’une requête distribuée : un INSERT distribué exécuté en arrière-plan lance ses requêtes par segment au premier plan, au sein de la requête initiale en arrière-plan.

Soumettre une requête en arrière-plan

Protocole TCP natif

Avec clickhouse-client, passez run_query_in_background en tant que paramètre de ligne de commande :
Vous pouvez également utiliser une clause SETTINGS intégrée :
Le protocole natif transmet les query settings séparément du texte SQL. clickhouse-client parse la plupart des query settings intégrés et les envoie dans cette section de settings. Les drivers utilisant le protocole natif peuvent, à la place, passer run_query_in_background dans leur map de settings par requête, sans modifier le texte SQL. Le protocole natif ne renvoie pas de query_id généré par le server. Les native clients doivent générer un ID unique et l’envoyer avec la requête. clickhouse-client --echo-query-id s’en charge et affiche l’ID avant de soumettre la requête :

HTTP protocol

Pour les requêtes HTTP, passez run_query_in_background comme paramètre d’URL :
La réponse contient l’ID de requête généré dans le header X-ClickHouse-Query-Id :
Ce header ne parvient qu’au client qui lit la réponse. Lorsque vous avez besoin d’un handle sur la query qui ne dépende pas de la réception de la réponse, envoyez plutôt votre propre query_id sous forme de paramètre d’URL. Le client connaît ainsi l’ID avant même d’émettre la request, et peut surveiller ou KILL la query sur le node qui l’a acceptée, même s’il n’en voit jamais la réponse :
Contrairement au protocole natif, HTTP ne permet pas d’activer l’exécution en arrière-plan via une clause SQL SETTINGS intégrée :
Cette requête renvoie une exception BAD_ARGUMENTS. Le gestionnaire HTTP doit déterminer s’il crée un contexte de requête détaché avant l’analyse du corps de la requête. Transmettez le paramètre dans l’URL, ou configurez-le au niveau de l’utilisateur ou du profil.

Surveiller l’exécution

Utilisez le query_id pour vérifier si une requête est en cours d’exécution :
Une fois la requête terminée, consultez system.query_log pour connaître son status final :
La requête de soumission peut réussir même si l’exécution en arrière-plan échoue ensuite. Dans ce cas, l’exception est consignée dans system.query_log au lieu d’être renvoyée sur la connexion d’origine.
system.processes, system.query_log et KILL QUERY sont locaux au nœud : chacun ne voit que les requêtes du serveur qui y répond.Une requête en arrière-plan appartient au serveur qui l’a acceptée, lequel n’est pas nécessairement celui que votre prochaine requête atteindra via un load balancer. Interrogez plutôt l’ensemble du cluster :
Il en va de même pour system.query_log, et l’annulation nécessite la forme applicable à l’ensemble du cluster :

Délai de flush du query log

Les entries sont mises en buffer avant d’apparaître dans system.query_log. Pour ClickHouse self-managed, l’exemple de server configuration définit query_log.flush_interval_milliseconds à 7500. Les entries de ClickHouse Cloud peuvent mettre jusqu’à 30 secondes avant d’apparaître. Tenez compte de ce délai lorsque vous surveillez des queries d’arrière-plan de courte durée. Sur un server self-managed, les utilisateurs disposant de privileges suffisants peuvent forcer le flush du query log. Nommez explicitement le log afin de ne pas toucher aux autres logs système :
Le flush a lieu sur le serveur qui reçoit le statement. Une query en arrière-plan est suivie par le serveur qui l’a acceptée, lequel n’est pas nécessairement celui auquel votre session en cours est connectée : sur un cluster, effectuez donc un flush partout avant de rechercher la query :
Un flush à l’échelle du cluster se contente de faire écrire à chaque serveur ses propres entries mises en buffer. Cela ne rend pas visible localement le system.query_log d’un autre serveur : il faut donc toujours lire le log via clusterAllReplicas, comme décrit dans Surveiller l’exécution.
Dernière modification le 26 septembre 2026