← 학습 카테고리

Learn

ClickHouse

47개 모듈 · 현재 40번째

ClickHouse 모듈 40/47 clickhouse-learn-40

ReplacingMergeTree의 is_deleted 컬럼 — 엔진 차원에서 소프트 삭제를 자동화한다

ClickHouse ReplacingMergeTree is_deleted 컬럼 및 ATTACH/DETACH PARTITION 공식 문서 종합 (웹 리서치, 2026) — ClickHouse 공식 문서(guides/replacing-merge-tree, reference/statements/alter/partition) + Altinity 기술 블로그 ClickHouse 공식문서 Working with the ReplacingMergeTree engine

이 모듈을 다 읽으면

  • is_deleted 컬럼이 clickhouse-learn-04의 ReplacingMergeTree '최신 값으로 덮어쓰기'를 삭제까지 확장한다는 것을 설명할 수 있다
  • clean_deleted_rows='Always'와 FINAL이 각각 어떤 역할을 하는지 구분할 수 있다

clickhouse-learn-04에서 다룬 ReplacingMergeTree(같은 키의 나중 값으로 덮어쓰기)와 clickhouse-learn-32의 Lightweight DELETE(마스크 컬럼 기반 삭제)를 전제로, ReplacingMergeTree 엔진 자체에 삭제 개념을 내장한 is_deleted 컬럼을 정리한다.

is_deleted_column — ReplacingMergeTree에 삭제 개념을 내장한다

ENGINE = ReplacingMergeTree([버전컬럼], [is_deleted_column]) ORDER BY <컬럼목록> 문법으로, ReplacingMergeTree에 삭제 여부를 나타내는 컬럼을 지정할 수 있다(23.2+). clickhouse-learn-04의 ReplacingMergeTree는 원래 '같은 키의 최신 버전으로 덮어쓰기'만 했는데, is_deleted 컬럼을 지정하면 그 최신 버전이 '삭제됐다'는 것까지 같은 방식(새 행을 INSERT하는 것)으로 표현할 수 있게 된다 — deleted=1인 새 행을 넣는 것 자체가 '이 키는 지워졌다'는 삭제 마킹이 되는 셈이다.

핵심 포인트

  • ENGINE = ReplacingMergeTree([버전컬럼], [is_deleted_column])로 삭제 여부 컬럼 지정(23.2+)
  • module04의 '최신 버전으로 덮어쓰기' 방식을 그대로 이용 — deleted=1인 새 행을 INSERT하는 것 자체가 삭제 마킹

23.3부터 — 쿼리 시점 자동 필터링과 clean_deleted_rows

23.3부터는 이 'deleted' 컬럼이 지정되면 ClickHouse가 쿼리 시점에 deleted=1인 행을 자동으로 걸러내 준다 — 사용자가 매번 WHERE deleted=0을 붙일 필요가 없다. clean_deleted_rows='Always' 설정을 주면, 병합이 일어날 때 삭제 표시된 행을 자동으로 실제 제거해줘 별도 조치가 필요 없다. 다만 clickhouse-learn-32의 Lightweight DELETE와 근본적인 차이가 있다 — Lightweight DELETE는 임의 MergeTree 엔진에 즉시 적용되는 반면, is_deleted는 ReplacingMergeTree 전용이고 '삭제'가 실제로는 새 행 INSERT로 표현된다는 점이 다르다.

핵심 포인트

  • 23.3부터 deleted 컬럼 지정 시 쿼리 시점에 deleted=1 행을 자동 필터링, clean_deleted_rows='Always'로 병합 시 자동 실제 제거
  • clickhouse-learn-32의 Lightweight DELETE(임의 MergeTree에 즉시 적용)와 근본적으로 다른 접근 — is_deleted는 ReplacingMergeTree 전용이고 삭제가 새 행 INSERT로 표현됨

여전히 남는 함정 — 병합 전에는 FINAL 없이 정확하지 않다

clickhouse-learn-04에서 이미 다룬 함정이 여기서도 그대로 적용된다 — 중복 제거(그리고 이제는 삭제 반영까지)는 백그라운드 병합 시점에만 일어나므로, 평범한 SELECT는 여전히 중복된 행이나 이미 논리적으로 삭제된 행을 반환할 수 있다. 병합 전에도 정확한 결과가 필요하면 FINAL 수식어를 써야 중복 제거와 삭제 반영이 쿼리 실행 시점에 완료된 채로 결과를 받을 수 있다.

핵심 포인트

  • 중복 제거·삭제 반영은 백그라운드 병합 시점에만 일어남 — 평범한 SELECT는 여전히 중복/삭제된 행을 반환할 수 있음
  • 즉시 정확한 결과가 필요하면 FINAL 수식어로 쿼리 실행 시점에 중복 제거+삭제 반영을 완료(module04의 FINAL 트레이드오프가 그대로 적용)