Bad SQL查杀最佳实践

更新时间:
复制 MD 格式

在高QPS集群中,异常SQL可能消耗大量CPU和内存资源,导致集群性能下降甚至OOM。本文介绍如何快速发现并终止异常SQL,以及如何配置自动防护策略,避免资源耗尽。

步骤一:发现Bad SQL

使用以下命令查看正在运行的查询,找出CPU或内存消耗异常的SQL。

说明

建议优先使用SHOW PROC '/global_current_queries'(需v3.4+),该命令可查看所有FE节点的运行中查询。v3.4以下版本使用SHOW PROC '/current_queries',仅能查看当前FE节点。

-- 查看所有FE节点正在运行的查询(v3.4+,推荐)
SHOW PROC '/global_current_queries';

-- v3.4以下版本,只能查看当前FE节点
SHOW PROC '/current_queries';

查询结果中重点关注以下字段:

指标

高风险阈值

说明

CPUTime

> 60s

CPU消耗异常,可能是笛卡尔积或缺少谓词。

MemoryUsage

> 2 GB

内存占用过高,有OOM风险。

步骤二:查杀Bad SQL

找到异常SQL后,通过ConnectionIdQueryId终止查询。

-- 通过ConnectionId终止(从步骤一结果获取)
KILL QUERY <ConnectionId>;

-- 通过QueryId终止(v3.1+)
KILL QUERY '<QueryId>';
说明

通过QueryId终止查询需要StarRocks v3.1及以上版本。ConnectionId为数字,不需要引号;QueryId为字符串,需要用单引号。

步骤三:分析原因(可选)

终止异常SQL后,可以开启慢查询Profile采集,分析SQL异常的根本原因,避免问题再次发生。

开启慢查询Profile采集

设置慢查询阈值,只对超过阈值的查询采集Profile,对正常查询无性能影响。

-- 开启慢查询Profile采集(只对超阈值查询生效,正常查询零开销)
SET GLOBAL big_query_profile_threshold = '30s';

查看和分析Profile

-- 查看已采集的Profile
SHOW PROFILELIST LIMIT 50;

-- 分析指定查询的执行瓶颈
ANALYZE PROFILE FROM '<query_id>';

自动防护配置

除了手动查杀,还可以通过资源组和查询队列实现自动防护,从根源上避免异常SQL耗尽集群资源。

资源组:自动拒绝超限查询

通过资源组(Resource Group)对CPU和内存设置上限,超过限制的查询将被自动拒绝。

SET GLOBAL enable_pipeline_engine = true;

CREATE RESOURCE GROUP bigQueryGuard
TO (db='your_db')
WITH (
    'cpu_weight' = '10',
    'mem_limit' = '20%',
    'big_query_cpu_second_limit' = '300',      -- CPU超过300s自动拒绝
    'big_query_mem_limit' = '5368709120'        -- 内存超过5GB自动拒绝
);
重要

以上参数值仅供参考,请根据实际集群配置和业务需求调整big_query_cpu_second_limitbig_query_mem_limit的值。

查询队列:防止并发过载

当集群资源使用达到阈值时,新查询将进入队列等待,避免过载。

SET GLOBAL enable_query_queue_select = true;
SET GLOBAL query_queue_concurrency_limit = 100;
SET GLOBAL query_queue_mem_used_pct_limit = 0.9;
SET GLOBAL query_queue_cpu_used_permille_limit = 800;
SET GLOBAL query_queue_max_queued_queries = 100;
SET GLOBAL query_queue_pending_timeout_second = 480;

各参数说明如下。

参数

说明

enable_query_queue_select

是否启用查询队列,设置为true开启。

query_queue_concurrency_limit

最大并发查询数,超过此值的查询将排队等待。

query_queue_mem_used_pct_limit

内存使用百分比阈值,超过后新查询排队。

query_queue_cpu_used_permille_limit

CPU使用千分比阈值(800表示80%),超过后新查询排队。

query_queue_max_queued_queries

队列最大等待查询数,超过后新查询将被拒绝。

query_queue_pending_timeout_second

排队超时时间(秒),超时后查询将被取消。

说明

以上参数值仅供参考,请根据实际集群规模和业务负载情况调整。

速查

操作

命令或方式

发现Bad SQL

SHOW PROC '/global_current_queries'

查杀

KILL QUERY <ConnectionId>

Profile采集

SET GLOBAL big_query_profile_threshold='30s'

自动防护

资源组big_query_cpu/mem_limit + 查询队列