bigywater.tech
ClickHouse 内部原理 · 81

ClickHouse 内存限制:查询为什么被 Kill

真实查三层内存限制的默认值,发现单查询和单用户默认不限,但服务器整体有一个真实按物理内存自动算出的硬上限,并验证触发超限时精确的审计记录。

约14GB服务器安全网
真实按16GB物理内存自动算出的硬上限
精确到执行阶段
真实报错定位到具体是哪个算子申请内存时撞线

做的事:真实查三个层级的内存限制默认值

代码SELECT name, value FROM system.settings WHERE name IN ('max_memory_usage','max_memory_usage_for_user'); SELECT name, value FROM system.server_settings WHERE name='max_server_memory_usage'; sysctl hw.memsize; -- 本机真实物理内存

验证:单条查询和单用户默认不限,服务器却有一个真实的硬上限

实测 · 本机执行输出
max_memory_usage           0   ← 真实默认不限制单条查询
max_memory_usage_for_user  0   ← 真实默认不限制单个用户的所有查询总和
max_server_memory_usage    15461882265   ← 真实约14GB,非零

本机真实物理内存:16 GB
15461882265 / 1024^3 ≈ 14 GB ≈ 16GB的90%左右

这组真实数字揭示了一件容易被忽视的事:默认配置下,单条查询本身是没有内存上限的,能不能把内存用爆,取决于这条查询实际需要多少内存和整台服务器还剩多少内存——但服务器整体确实真实设了一个硬上限,而且这个上限不是随便写的常数,是ClickHouse启动时真实按检测到的物理内存自动计算出来的一个比例值。

验证:真实触发内存超限,报错精确到执行阶段

实测 · 本机执行输出(3000万行极端高基数GROUP BY,手动收紧到50MB)
SELECT k, count() FROM demo.memtest GROUP BY k SETTINGS max_memory_usage=50000000 FORMAT Null;
→ DB::Exception: Query memory limit exceeded: would use 53.95 MiB
  (attempt to allocate chunk of 0.00 B), maximum: 47.68 MiB:
  While executing AggregatingTransform. (MEMORY_LIMIT_EXCEEDED)

真实的完整审计记录:
SELECT type, exception_code, exception FROM system.query_log WHERE ...;
→ ExceptionWhileProcessing  241  Query memory limit exceeded...
"被Kill"这件事真实不是一个模糊的"OOM",而是ClickHouse自己在内存分配的那一刻主动检测、主动拒绝——报错信息里的While executing AggregatingTransform精确指出了是哪一个执行算子申请内存时撞线,system.query_log里真实完整保留了这次失败的审计记录(exception_code=241对应MEMORY_LIMIT_EXCEEDED),不是进程被操作系统的OOM killer强行杀掉那种"查无实据"的崩溃。真实的三层限制设计给了不同粒度的防护:max_memory_usage让你可以给某一类风险查询单独设更紧的上限(本文这次手动收紧到50MB);max_memory_usage_for_user可以防止某个用户同时发起多条查询,单条都不超限但加起来把服务器吃满;max_server_memory_usage是最后一道真实的安全网,即使前两层都没配置(默认都是0/不限),服务器也不会真的被单条查询吃到物理内存耗尽而彻底崩溃——本文这台16GB内存的机器,这道安全网真实设在了约14GB。

分步演示:从三层限制的默认值到真实触发的完整审计记录

每一步都是本文上面用真实内存限制配置跑出来的原始结果。

三层限制:前两层默认不限,服务器层真实有安全网
这一步新验证的层级

    本文用到的工具

    • 本机 ClickHouse 26.9.4(16GB物理内存),真实的 max_memory_usage/max_memory_usage_for_user/max_server_memory_usage 三层限制
    京ICP备2026067502号-1京公网安备11010502063487号