IT System Management/Database

ClickHouse + ZooKeeper 클러스터에서 손상된 레플리카 복구하기

iseop 2025. 10. 5. 12:12

ClickHouse는 OLAP(Online Analytical Processing)을 위한 컬럼 지향형 DBMS입니다. 전통적인 DBMS는 행을 처리하는 데 적합하기 때문에 OLAP에 사용하기에는 비효율적인 구조라고 합니다.

ClickHouse는 고가용성과 부하분산을 위해 클러스터링을 지원하는데, 자체의 replication 기능과 ZooKeeper(공식 문서에서는 ClickHouse-Keeper를 권장)를 사용합니다. 클러스터로 구성된 ClickHouse 레플리카 중 DB가 손상되어 장기간 read-only 상태로 방치된 노드가 있을 때 이를 재구성하는 방법을 정리해 보았습니다.

 

error_log 테이블을 조회해 보면 TABLE_IS_READ_ONLY, TIMEOUT_EXCEEDED 두 종류의 오류 로그가 있었습니다.

SELECT
    event_time,
    error
FROM system.error_log
ORDER BY event_time DESC;

 


1. 손상된 테이블 및 ZooKeeper 리소스 제거

- DB: default (Atomic)

- 테이블: traces (ReplicatedReplacingMergeTree)

 

ClickHouse 노드에서 작업: 

clickhouse-client
(패스워드 입력)
DROP TABLE default.traces;

 

ZooKeeper 노드에서 작업:

zkCli.sh
(패스워드 입력)
deleteall /clickhouse/tables/손상된 테이블의 UUID/손상된 shard 명칭



2. 정상 노드의 스키마 복사

clickhouse-client
(패스워드 입력)
SHOW CREATE TABLE default.traces FORMAT CSV;


출력을 복사해 둔다.

 


3. 스키마 생성 SQL의 매크로 변수 처리

CREATE TABLE default.traces
(
    trace_id String,
    service String,
    span_id String,
    start_time DateTime,
    ...
)
ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/{uuid}/{shard}', {replica})
...

{uuid}: 해당 테이블의 UUID로 직접 치환해 주어야 한다. 정상 노드의 저장소에 존재하는 심볼릭 링크를 보고 확인할 수 있다.

{shard}, {replica}: 해당 노드의 환경 변수에 저장되어 있었음. 이런 경우에는 쿼리의 매크로(중괄호) 부분을 clickhouse-client가 알아서 값으로 치환해준다.

ls -l /DB 파일 저장 경로/data/data/default/
... traces -> ../../store/00000000-0000-0000-0000-000000000000

 

 

4. 테이블 생성
테이블을 생성하면 정상 노드로부터 데이터를 가져오기 시작한다.

CREATE TABLE default.traces
...



5. 데이터 복제 확인

테이블의 행 개수를 정상 노드와 비교해 본다.

SELECT count() FROM default.traces;

 

system.replicas 테이블을 조회해 본다.

SELECT
    is_readonly,
    log_pointer,
    replica_is_active
FROM system.replicas
WHERE table='traces';