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 트레이드오프가 그대로 적용)