概述
后台查询允许客户端通过设置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 控制。
不受支持的查询形式
后台查询的存活时间比提交它的 connection 更长,因此 server 必须在接受该查询的那一刻就已具备运行它所需的一切条件。 不满足该条件的 request 会在提交请求的 connection 上被同步拒绝,查询不会启动。通过连接流式传输的数据
如果在分发查询后,服务器仍需从提交该查询的连接中读取数据,则该INSERT 会被拒绝。
这会影响 INSERT ... FORMAT ... 以及通过 input 读取数据的查询。此类请求会被拒绝,并返回 A query whose data streams over the connection cannot be run in the background:
ClickHouse 客户端 会将 INSERT ... FORMAT ... 的数据拆分为独立的 packet 发送,因此在 原生协议 上,这种形式永远无法在后台运行。
在 HTTP 上,只要完整的查询及其数据能装入初始的 parsing buffer (其大小受 max_query_size 限制) ,两种形式都可以被接受。
其中也包括通过 input 读取 inline payload 的 HTTP 查询。如果 body 较大,数据会在已缓冲的 query text 之后继续以流式方式传输,此时请求会被拒绝。
请不要依赖这一大小界限:对于必须在后台加载的数据,请使用 INSERT ... SELECT,或 url、s3 之类的 table function。
其他被拒绝的请求
该设置永远不会传播到分布式查询的次级查询:后台执行的分布式
INSERT
会在后台运行的初始查询内,以前台方式执行各个分片上的查询。
提交后台查询
原生 TCP 协议
使用 ClickHouse 客户端时,将run_query_in_background 作为命令行设置传入:
SETTINGS 子句:
run_query_in_background,从而无需改动 SQL 文本。
原生协议不会返回由服务端生成的 query_id。原生客户端应自行生成一个唯一 ID,并随查询一并发送。
clickhouse-client --echo-query-id 即可实现这一点,它会在提交查询前打印该 ID:
HTTP protocol
对于 HTTP 请求,请将run_query_in_background 作为 URL 参数传递:
X-ClickHouse-Query-Id 响应头中包含生成的查询 ID:
query_id。
这样客户端在发起请求之前就已知道该 ID,即使始终未收到响应,也能在接收请求的节点上监控或 KILL 该查询:
SETTINGS 子句启用后台执行:
BAD_ARGUMENTS 异常。HTTP handler 必须在解析请求体之前决定是否创建 detached 查询 Context。
请在 URL 中传递该设置,或在用户或 profile 级别进行配置。
监控执行
使用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 读取日志。