Skip to main content

该异常的含义

当某个 INSERT 会使 MergeTree 表中的活跃数据分区片段数量超过已配置的限制时,ClickHouse 会抛出 parts 过多 异常。该异常通常还会包含消息:Merges are processing significantly slower than inserts 每个同步 INSERT 至少会创建一个数据分区片段。如果一次 insert 包含属于多个分区值的行,ClickHouse 可能会为每个受影响的分区各创建一个 parts。后台合并会将较小的 parts 合并为较大的 parts;但如果新 parts 的创建速度快于 ClickHouse 的合并速度,活跃 parts 的数量就会持续增长。 该异常可能由以下任一设置触发:

诊断原因

使用以下查询找出活跃 parts 数量最多的分区:
要检查由 max_parts_in_total 对整个表施加的限制,请统计表中的所有活跃 parts:
常见原因包括:
  • 频繁进行小批量同步插入。
  • 分区键基数过高。
  • 单次插入包含来自多个分区值的行。
  • 由于存储吞吐量受限、可用磁盘空间不足或其他资源争用,后台合并跟不上。
你可以在 system.merges 中查看当前正在运行的合并任务,并查阅服务器日志中的合并失败记录。

解决此异常

批次同步插入

在插入前,先在客户端将数据行分批。每个批次应至少包含 1,000 行,理想情况下为 10,000–100,000 行。目标是大约每秒执行一次同步 INSERT。插入次数更少、单次插入量更大,可以生成更少的 parts,并减少后台合并所需的工作量。

使用异步插入

如果不方便在客户端进行批处理,请使用异步插入,这样 ClickHouse 就能在服务端对传入数据进行批处理:
保持 wait_for_async_insert = 1,这样 ClickHouse 只会在数据成功写入后才确认插入。

检查分区键

使用低基数的分区键,并避免按用户或请求标识符等值进行分区。ClickHouse 仅会在同一分区内合并 parts,因此分区数量过多会妨碍高效合并。有关建议,请参阅选择分区键

排查合并瓶颈

如果插入操作已经进行了适当的批处理,请检查存储性能、可用磁盘空间以及相互争用的后台任务。合并速率取决于存储系统、表引擎、排序键、压缩,以及可用的 CPU 和 I/O 能力。

不要把提高 part 限制作为首要修复措施

提高 parts_to_throw_insertmax_parts_in_total 并不能解决 parts 过多创建的根本原因。提高限制虽然可以推迟异常出现,但也可能增加文件系统和元数据开销,并降低查询性能。只有在找出原因并确认系统容量充足后,才应更改这些设置。

验证恢复情况

更改插入策略或分区方案后,再次运行诊断查询。活跃 parts 的数量应趋于稳定,并随着后台合并逐渐跟上而开始下降。继续监控插入失败、可用磁盘空间以及 system.merges,直到积压清空。
最后修改于 2026年8月14日