Triệu chứng chính: insert bị từ chối với Too many parts (...). Merges are processing significantly slower than inserts (TOO_MANY_PARTS), query báo Memory limit (for query) exceeded ... (MEMORY_LIMIT_EXCEEDED), disk đầy, hoặc dashboard flow (Akvorado) load rất chậm.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
Too many parts (...) ... (TOO_MANY_PARTS) |
Insert nhiều batch nhỏ, mỗi insert tạo một part; merge không theo kịp | Gom batch lớn hơn (≥ vài nghìn dòng, ≤ 1 insert/giây/bảng), hoặc bật async_insert = 1 |
| Như trên, partition quá nhỏ | PARTITION BY quá chi tiết (theo giờ, theo exporter) |
Partition theo ngày/tháng; chỉ tăng parts_to_throw_insert khi đã hiểu rõ |
Memory limit (for query) exceeded: would use ... (MEMORY_LIMIT_EXCEEDED) |
GROUP BY cardinality cao, JOIN bảng lớn | Lọc thời gian chặt hơn, max_bytes_before_external_group_by, đặt bảng nhỏ bên phải JOIN |
Memory limit (total) exceeded |
Tổng RAM server vượt max_server_memory_usage |
Giảm query song song, kiểm tra merge lớn trong system.merges |
Cannot reserve ..., not enough space (NOT_ENOUGH_SPACE) |
Disk đầy, merge cần chỗ trống bằng tổng kích thước part nguồn | Xoá partition cũ, đặt TTL, mở rộng disk |
Timeout exceeded: elapsed ... (TIMEOUT_EXCEEDED) |
Query quét quá nhiều dữ liệu | Thêm điều kiện trên cột của ORDER BY/partition, dùng bảng tổng hợp |
Too many simultaneous queries |
Dashboard refresh dày, nhiều người xem | Tăng refresh interval Grafana, cache, max_concurrent_queries |
Table is in readonly mode |
Bảng Replicated mất kết nối ZooKeeper/Keeper | Kiểm tra Keeper, system.replicas.is_readonly |
Mutation (ALTER ... DELETE/UPDATE) không xong |
Mutation lỗi hoặc rất nặng | Xem system.mutations.latest_fail_reason, KILL MUTATION |
Các bước khoanh vùng
- Lỗi gần đây là gì:
system.errorsvà log server. - Part và merge: số part active mỗi partition, merge đang chạy.
- Disk:
system.disks, dung lượng theo bảng (system.parts). - Query: query nặng nhất trong
system.query_log, query đang chạy trongsystem.processes. - Sửa: chỉnh batch insert / TTL / query, rồi theo dõi lại.
OPTIMIZE TABLE ... FINAL ép merge toàn bộ, rất tốn IO và cần nhiều disk trống. Không dùng làm cách sửa TOO_MANY_PARTS trên bảng lớn trong giờ cao điểm.
Kiểm tra nhanh
-- Lỗi gần nhất
SELECT name, value, last_error_time, last_error_message
FROM system.errors ORDER BY last_error_time DESC LIMIT 10;
-- Số part active theo partition (cảnh báo khi lên hàng trăm)
SELECT database, table, partition, count() AS parts, sum(rows) AS rows
FROM system.parts WHERE active
GROUP BY database, table, partition ORDER BY parts DESC LIMIT 20;
-- Merge đang chạy
SELECT database, table, round(elapsed) AS sec, round(progress * 100) AS pct,
num_parts, formatReadableSize(memory_usage) AS mem
FROM system.merges;
-- Mutation chưa xong
SELECT database, table, mutation_id, command, latest_fail_reason
FROM system.mutations WHERE NOT is_done;
-- Disk
SELECT name, path, formatReadableSize(free_space) AS free, formatReadableSize(total_space) AS total
FROM system.disks;
-- Dung lượng theo bảng, tỉ lệ nén
SELECT table,
formatReadableSize(sum(data_compressed_bytes)) AS compressed,
formatReadableSize(sum(data_uncompressed_bytes)) AS raw,
round(sum(data_uncompressed_bytes) / sum(data_compressed_bytes), 1) AS ratio
FROM system.parts WHERE active
GROUP BY table ORDER BY sum(data_compressed_bytes) DESC;
-- 10 query nặng nhất 1 giờ qua (cùng dạng query gom lại)
SELECT normalized_query_hash, count() AS n,
round(avg(query_duration_ms)) AS avg_ms,
formatReadableSize(max(memory_usage)) AS max_mem,
formatReadableSize(sum(read_bytes)) AS read,
any(query) AS sample
FROM system.query_log
WHERE type = 'QueryFinish' AND event_time > now() - INTERVAL 1 HOUR
GROUP BY normalized_query_hash ORDER BY sum(query_duration_ms) DESC LIMIT 10;
-- Query đang chạy
SELECT query_id, user, round(elapsed) AS sec, formatReadableSize(memory_usage) AS mem, query
FROM system.processes ORDER BY elapsed DESC;
-- Query có dùng primary key / partition pruning không
EXPLAIN indexes = 1
SELECT count() FROM flows WHERE TimeReceived > now() - INTERVAL 1 HOUR;Lệnh xử lý:
KILL QUERY WHERE query_id = '<id>';
KILL MUTATION WHERE mutation_id = '<id>';
ALTER TABLE flows DROP PARTITION '<partition-id>'; -- lấy tên từ system.parts.partition
ALTER TABLE flows MODIFY TTL TimeReceived + INTERVAL 30 DAY;
SYSTEM FLUSH LOGS; -- ghi query_log ngay
SELECT * FROM flows WHERE TimeReceived > now() - INTERVAL 1 HOUR
SETTINGS max_memory_usage = 8000000000, max_execution_time = 60;journalctl -u clickhouse-server -n 200 --no-pager
tail -n 200 /var/log/clickhouse-server/clickhouse-server.err.log
df -h /var/lib/clickhouse && du -sh /var/lib/clickhouse/storeQuery top talkers mẫu xem ClickHouse top talkers. Xử lý disk đầy ở tầng OS xem disk đầy.