6편 · 약 13분
운영과 모니터링
모니터링의 구조
ClickHouse는 운영 상태 대부분을 system 데이터베이스의 시스템 테이블로 노출한다. 외부 모니터링 도구 없이도 SQL로 진단할 수 있다는 것이 장점이다.
쿼리 레이어
system.query_log
system.processes
스토리지 레이어
system.parts
system.merges
system.part_log
복제 레이어
system.replication_queue
system.replicas
서버 레이어
system.metrics
system.events
system.asynchronous_metrics
핵심 시스템 테이블 요약
| 테이블 | 내용 | 주요 용도 |
|---|---|---|
system.query_log | 완료·실패한 쿼리 이력 | 슬로우 쿼리, 오류 분석 |
system.processes | 현재 실행 중인 쿼리 | 장시간 쿼리 탐지, KILL 대상 식별 |
system.parts | 테이블별 파트 목록 | 파트 수 모니터링, 파티션 상태 |
system.merges | 진행 중인 백그라운드 병합 | 병합 속도, 적체 진단 |
system.replicas | 복제 테이블 상태 | 복제 지연, 큐 깊이 |
system.replication_queue | 복제 대기 작업 목록 | 복제 오류 원인 파악 |
system.metrics | 현재 순간 카운터 | 커넥션 수, 스레드 수 |
system.events | 누적 이벤트 카운터 | SELECT·INSERT 횟수 추세 |
system.asynchronous_metrics | 백그라운드 수집 지표 | 메모리·CPU 시계열 |
쿼리 성능 진단
슬로우 쿼리 찾기
SELECT
left(query, 100) AS query_snippet,
query_duration_ms,
read_rows,
formatReadableSize(read_bytes) AS read_size,
memory_usage
FROM system.query_log
WHERE type = 'QueryFinish'
AND query_duration_ms > 2000
AND event_date = today()
ORDER BY query_duration_ms DESC
LIMIT 20;read_bytes가 크고result_rows가 작으면 인덱스 효율이 낮다.memory_usage가 높으면 집계·정렬 중간 상태가 메모리에 많이 올라간 것.
현재 실행 중인 장시간 쿼리
SELECT
query_id,
elapsed,
read_rows,
left(query, 80) AS query_snippet
FROM system.processes
WHERE elapsed > 30
ORDER BY elapsed DESC;
-- 필요 시 강제 종료
KILL QUERY WHERE query_id = '<id>';오류 빈도 추적
SELECT
toStartOfHour(event_time) AS hour,
count() AS error_count,
groupArray(10)(exception) AS sample_exceptions
FROM system.query_log
WHERE type = 'ExceptionWhileProcessing'
AND event_date >= today() - 1
GROUP BY hour
ORDER BY hour;Parts 관리 — "Too Many Parts" 문제
ClickHouse에서 가장 자주 만나는 운영 문제 중 하나다.
원인
INSERT가 들어올 때마다 새 파트가 생긴다. 백그라운드 병합이 소규모 삽입 속도를 따라잡지 못하면 파트 수가 계속 늘어난다.
파트 수가 임계값을 초과하면 ClickHouse가 삽입을 지연(delay)하거나 예외(throw)를 던진다.
- ClickHouse 23.6 이전: delay 150, throw 300
- ClickHouse 23.6 이후: throw 기본값 3,000으로 상향
진단
SELECT
database,
table,
partition,
count() AS active_parts
FROM system.parts
WHERE active
GROUP BY database, table, partition
HAVING active_parts > 100
ORDER BY active_parts DESC;100개 미만: 정상, 100~300개: 경고, 300개 초과: 즉시 조치.
해결 방법
- 삽입 배치 크기 키우기 — 가장 근본적인 해결책. 행 수천~수만 건을 묶어 한 번에 INSERT한다.
- async_insert 활성화 — 클라이언트가 작은 삽입을 보낼 수밖에 없을 때 서버 측 버퍼링으로 배치를 합친다.
SET async_insert = 1;
SET wait_for_async_insert = 1;- 병합 스레드 수 늘리기
<!-- config.xml -->
<background_pool_size>16</background_pool_size>병합 진행 모니터링
SELECT
table,
round(progress * 100, 1) AS progress_pct,
elapsed,
formatReadableSize(total_size_bytes_compressed) AS merge_size
FROM system.merges
ORDER BY elapsed DESC;병합이 오래 걸리는 테이블이 보이면 그 테이블의 삽입 패턴을 점검한다.
복제 모니터링
ReplicatedMergeTree 계열을 쓰는 경우 복제 지연이 핵심 지표다.
-- 복제 지연 및 큐 상태
SELECT
database,
table,
is_leader,
queue_size,
inserts_in_queue,
merges_in_queue,
last_queue_update_exception
FROM system.replicas
WHERE queue_size > 0
ORDER BY queue_size DESC;queue_size> 0이고 계속 증가하면 복제 적체.last_queue_update_exception에 오류가 있으면 복제가 멈춘 것.
-- 복제 큐에서 오류 항목만
SELECT
table,
type,
last_exception,
num_tries,
create_time
FROM system.replication_queue
WHERE last_exception != ''
ORDER BY create_time DESC;메모리와 디스크 관리
메모리 현황
SELECT
metric,
formatReadableSize(value) AS val
FROM system.asynchronous_metrics
WHERE metric IN (
'MemoryResident',
'MemoryVirtual',
'MarkCacheBytes',
'UncompressedCacheBytes'
)
ORDER BY metric;MarkCacheBytes: 스파스 인덱스 마크 캐시 — 부족하면 매 쿼리마다 마크 파일을 디스크에서 읽는다.UncompressedCacheBytes: 압축 해제된 데이터 블록 캐시.
디스크 파티션별 사용량
SELECT
name,
path,
formatReadableSize(free_space) AS free,
formatReadableSize(total_space) AS total,
round((1 - free_space / total_space) * 100, 1) AS used_pct
FROM system.disks;TTL 만료 파티션 즉시 정리
-- TTL 정리를 강제 트리거 (기본은 백그라운드에서 자동 실행)
ALTER TABLE events MATERIALIZE TTL;Prometheus + Grafana 연동
ClickHouse는 내장 Prometheus 엔드포인트를 제공한다.
<!-- config.xml -->
<prometheus>
<endpoint>/metrics</endpoint>
<port>9363</port>
<metrics>true</metrics>
<events>true</events>
<asynchronous_metrics>true</asynchronous_metrics>
</prometheus>이 엔드포인트를 Prometheus가 스크랩하고, Grafana의 ClickHouse 공식 대시보드(ID 14192)로 시각화한다. 주요 패널:
- 쿼리 처리량 (queries/s)
- 삽입 처리량 (rows/s)
- 파트 수 추이
- 병합 큐 길이
- 복제 지연
운영 알림 임계값 권고
| 지표 | 경고 | 위험 |
|---|---|---|
| 파티션당 활성 파트 수 | > 100 | > 300 |
병합 큐 깊이 (merges_in_queue) | > 50 | > 200 |
복제 큐 깊이 (queue_size) | > 100 | > 500 |
| 쿼리 오류율 (1분) | > 1% | > 5% |
| p99 쿼리 지연 | > 5s | > 30s |
| 디스크 사용률 | > 70% | > 85% |
운영 체크리스트
① query_log → 슬로우 쿼리·오류 확인
↓
② system.parts → 파트 수 이상 파티션 확인
↓
③ system.merges → 장시간 병합·적체 여부
↓
④ system.replicas → 복제 지연·오류 여부
↓
⑤ system.disks → 디스크 여유 공간
↓
이상 없음 → 완료 / 이상 있음 → EXPLAIN·KILL·설정 조정
- 슬로우 쿼리:
system.query_log에서query_duration_ms높은 쿼리 →EXPLAIN indexes=1분석. - 파트 폭증:
system.partsactive_parts > 100 → 삽입 배치 크기 점검, async_insert 고려. - 병합 적체:
system.mergeselapsed 높은 항목 →background_pool_size확인. - 복제 오류:
system.replicas.last_queue_update_exception존재 → ZooKeeper/ClickHouse Keeper 상태 점검. - 디스크 부족:
system.disks85% 초과 → TTL MATERIALIZE 또는 파티션 DROP.
한 줄 정리
ClickHouse 운영의 핵심 지표는 파트 수, 병합 큐, 복제 지연, 슬로우 쿼리 네 가지이며, 이 모두를 system.* 테이블에 직접 SQL로 질의하거나 Prometheus 엔드포인트로 수집해 Grafana에서 추적할 수 있다.
References
- https://clickhouse.com/docs/en/operations/system-tables/query_log
- https://clickhouse.com/docs/en/operations/system-tables/merges
- https://clickhouse.com/docs/en/operations/system-tables/parts
- https://clickhouse.com/docs/en/operations/system-tables/replicas
- https://clickhouse.com/docs/tips-and-tricks/too-many-parts
- https://chistadata.com/essential-clickhouse-metrics/
- https://severalnines.com/blog/clickhouse-monitoring-and-observability-decision-points/
- https://pulse.support/kb/clickhouse-system-tables
- https://clickhouse.com/blog/clickhouse-2025-roundup