The ClickHouse server is refusing new inserts because the ClickHouse storage engine for a specific table has accumulated too many small data parts.
This error, Too many parts, means the database can’t keep up with merging small data files on disk into larger ones. ClickHouse stores data in immutable "parts," and for efficiency, it periodically merges these smaller parts into bigger ones. When inserts are very frequent or the merge process is lagging, the number of small parts can overwhelm the system’s ability to manage them, leading to insert failures.
Here are the most common reasons and how to fix them:
1. Insufficient Merge Worker Threads: ClickHouse uses background threads to merge data parts. If there aren’t enough threads, merging falls behind.
- Diagnosis: Check the
merge_thread_activeandmerge_thread_active_maxmetrics insystem.merges. Ifmerge_thread_activeis consistently close tomerge_thread_active_max, you need more threads. - Fix: Increase the
max_concurrent_merges_in_queuesetting in your ClickHouse configuration file (e.g.,/etc/clickhouse-server/config.xmlor a file in/etc/clickhouse-server/config.d/). A good starting point is to increase it from its default (often 16) to32or64.<max_concurrent_merges_in_queue>64</max_concurrent_merges_in_queue> - Why it works: This setting directly controls how many merge operations ClickHouse can attempt to run concurrently, allowing it to process the backlog of small parts faster.
2. Extremely High Insert Rate: If your application is sending data to ClickHouse faster than it can merge, you’ll hit this limit. This is especially true for very small, frequent inserts.
- Diagnosis: Monitor the
insert_rows_readandinsert_bytes_readmetrics insystem.eventsfor the table in question. Compare this rate tomerge_rows_readandmerge_bytes_readinsystem.merges. If inserts are significantly outpacing merges, this is the cause. - Fix: Implement batching on your application side. Instead of sending 100 rows individually, send them in a single
INSERTstatement as a batch of 100. Tune batch size to be between 10,000 and 100,000 rows or 50-100MB per batch.-- Instead of: -- INSERT INTO my_table VALUES (1, 'a'); -- INSERT INTO my_table VALUES (2, 'b'); -- ... -- Do this: INSERT INTO my_table VALUES (1, 'a'), (2, 'b'), ...; - Why it works: Larger batches create fewer, bigger parts, which are more efficient for ClickHouse to merge. It drastically reduces the overhead of writing and managing many small parts.
3. Inefficient MergeTree Engine Configuration (e.g., min_bytes_for_wide_part too small):
The MergeTree family of engines has settings that control when ClickHouse decides to create wide parts (where columns are stored separately) versus compact parts (where columns are interleaved). If min_bytes_for_wide_part is too small, ClickHouse might create many small, wide parts, which are less efficient to merge.
- Diagnosis: Examine the
enginedefinition for your table.
Look forDESCRIBE TABLE my_table;min_bytes_for_wide_part. - Fix: Increase
min_bytes_for_wide_partto a larger value, like1073741824(1 GiB) or2147483648(2 GiB). This setting is usually configured per table or globally.
Or inALTER TABLE my_table MODIFY SETTING min_bytes_for_wide_part = 2147483648;config.xml:<merge_tree> <min_bytes_for_wide_part>2147483648</min_bytes_for_wide_part> </merge_tree> - Why it works: This encourages ClickHouse to delay creating wide parts until a part reaches a substantial size, reducing the number of small, inefficient parts that need merging.
4. Incorrect index_granularity for High-Cardinality Data:
index_granularity determines how many rows are in each index granule. If it’s too small, it can lead to more parts being created, especially with high-cardinality primary keys.
- Diagnosis: Check the
index_granularityfor your table.
The default isDESCRIBE TABLE my_table;8192. - Fix: Increase
index_granularity. A common recommendation for high insert rates is16384or32768.
Or inALTER TABLE my_table MODIFY SETTING index_granularity = 32768;config.xml:<merge_tree> <index_granularity>32768</index_granularity> </merge_tree> - Why it works: A larger index granularity means fewer index entries per part, reducing the metadata overhead and potentially the number of parts created, especially when combined with frequent inserts.
5. Disk I/O Bottleneck: If your storage is too slow, ClickHouse cannot perform merges fast enough, even with sufficient threads.
- Diagnosis: Monitor disk I/O utilization (e.g.,
iostat -xz 1on Linux) and latency. If disks are consistently at 100% utilization or have high read/write latencies, this is a bottleneck. Also, checksystem.eventsforread_bytesandwrite_bytesand compare them to your disk’s capabilities. - Fix: Upgrade to faster storage (SSDs, NVMe). If using network storage (NFS, S3), ensure it’s provisioned for sufficient IOPS and throughput.
- Why it works: Faster disks allow ClickHouse to read and write data parts much more quickly, enabling merges to keep pace with insert operations.
6. Excessive ALTER TABLE ... MODIFY COLUMN or DROP COLUMN Operations:
These operations can trigger background merges to rewrite parts, adding to the merge load.
- Diagnosis: Check
system.mergesfor a high number of merges related toALTERoperations. Look atsystem.query_logfor frequentALTERstatements. - Fix: Schedule
ALTERoperations during off-peak hours. If possible, consolidate multipleALTERoperations into a single one. Avoid frequent column additions/deletions on very active tables. - Why it works:
ALTERoperations, especiallyDROP COLUMN, require ClickHouse to rewrite data parts to remove or modify columns. Doing this frequently on a table with many small parts exacerbates the "too many parts" problem.
After addressing these, you might encounter Memory limit exceeded errors if your system is now trying to merge massive parts simultaneously.