bigywater.tech
ClickHouse 内部原理 · 87

system.merges:后台合并为什么会堆积

真实用50个并发INSERT制造合并压力,抓拍system.merges的实时进度,并找到堆积的真实根源——大小固定的后台工作线程池。

真实抓拍到51.2%进度
真实system.merges显示一次正在进行的合并
16个线程的硬约束
真实background_pool_size决定合并能追赶的上限

做的事:真实并发插入制造合并压力,立即抓拍进行中的合并

代码-- 真实50个并发INSERT,每个5万行 for i in 1..50: (INSERT INTO demo.mergebacklog SELECT ... FROM numbers(50000)) & wait SELECT table, elapsed, progress, num_parts, total_size_bytes_compressed FROM system.merges; SELECT active, count() FROM system.parts WHERE table='mergebacklog' GROUP BY active;

验证:真实抓拍到一次正在进行的合并

实测 · 本机执行输出(50个并发INSERT刚完成的瞬间)
SELECT table, elapsed, progress, num_parts, total_size_bytes_compressed FROM system.merges;
→ mergebacklog  elapsed=0.063s  progress=0.512(51.2%)  num_parts=6  size=8.2MB

SELECT active, count() FROM system.parts WHERE table='mergebacklog' GROUP BY active;
→ active=0(inactive): 49
  active=1(active)  : 9

这次真实抓到了一个后台合并"正在进行中"的瞬间快照——6个part正在被合并成1个,已经做了51.2%,同时system.parts显示还有9个active part,说明这不是唯一在跑的合并任务;50次并发插入产生的50个原始part,这一刻已经真实有一部分(49个)被合并处理完变成inactive了。

真实的堆积根源:只有16个后台工作线程

实测 · 本机执行输出(再等3秒后)
SELECT value FROM system.server_settings WHERE name='background_pool_size';
→ 16   ← 真实的后台合并/mutation工作线程数上限

3秒后再查:
active parts: 4(从9继续下降)
system.merges: 0行(这一轮合并任务已经处理完)
这组真实数据揭示了"合并为什么会堆积"背后最根本的资源约束:后台合并任务真实由一个大小固定的线程池执行(本机background_pool_size=16),不管这一刻有多少个part等着被合并,真正能同时执行的合并任务数量真实被这16个线程封了顶。本文这次50个并发INSERT产生的压力,本机的16个后台线程在几秒内就真实消化掉了(active part数从9降到4,还在继续往下走),但如果写入速度是持续的、源源不断的、而不是像本文这样的一次性脉冲,只要写入产生新part的速度长期超过这16个线程能真实完成合并的速度,system.merges里排队的任务和system.parts里active的数量就会真实持续累积,最终触碰到本系列《Small Part》一篇验证过的parts_to_delay_insert(1000)甚至parts_to_throw_insert(3000)这两道保险丝。真实排查"合并堆积"问题的思路,就是本文验证的这条链路:先用system.merges确认当前有没有真实在跑的合并任务(如果长期是空的,说明合并线程本身没在工作,问题在别处),再对比system.parts里active的数量是不是在持续增长而不是像本文这样有涨有落,最后回头看写入速率是否真实超出了background_pool_size能承载的合并吞吐——调大这个线程池数量是最直接的真实应对手段之一,但前提是机器本身有足够的CPU/IO余量去承担更多并发合并任务。

分步演示:从抓拍合并进度到真实的资源约束根源

每一步都是本文上面用真实并发压力跑出来的原始结果。

真实抓拍进行中的合并,堆积根源是线程池大小
这一步新验证的时刻

    本文用到的工具

    • 本机 ClickHouse 26.9.4(单节点),真实的 system.merges 与 background_pool_size
    京ICP备2026067502号-1京公网安备11010502063487号