뮤테이션(Avoid mutations)은 되도록 피하세요

뮤테이션(Avoid mutations)은 되도록 피하세요

ClickHouse에서 뮤테이션은 테이블의 기존 데이터를 수정하거나 삭제하는 작업을 뜻해요. 보통 ALTER TABLE ... DELETEALTER TABLE ... UPDATE 문을 사용하죠. 사용 빈도가 높은 작업이지만, 내부 동작 방식 때문에 남용하면 성능에 큰 부담을 줍니다. 이 문서에서는 뮤테이션이 왜 비싼 작업인지, 그리고 어떤 대안을 써야 하는지 설명할게요.

출처: 문서

본문

ClickHouse에서 뮤테이션(mutation) 은 테이블의 기존 데이터를 수정하거나 삭제하는 작업을 뜻합니다. 보통 ALTER TABLE ... DELETEALTER TABLE ... UPDATE 문을 사용하죠. 이 문장들이 표준 SQL 연산과 비슷해 보일 수 있지만, 내부적으로는 완전히 다르게 동작합니다. ClickHouse는 행을 제자리에서 수정하는 대신, 뮤테이션을 변경에 영향받는 전체 데이터 파트를 다시 쓰는 비동기 백그라운드 프로세스로 처리합니다. 이 방식은 ClickHouse의 컬럼 지향적이고 변경 불가능(immutable)한 저장 모델 때문에 필요한 것이며, 상당한 I/O와 리소스 사용을 유발할 수 있습니다. 뮤테이션이 실행되면 ClickHouse는 새로운 뮤테이션된 파트(mutated parts) 를 만드는 작업을 예약하고, 새 파트가 준비될 때까지 원본 파트는 그대로 둡니다. 준비가 끝나면 뮤테이션된 파트가 원본을 원자적으로 대체합니다. 하지만 이 작업은 파트 전체를 다시 쓰기 때문에, 단 한 행을 수정하는 사소한 변경조차도 대규모 재작성과 과도한 쓰기 증폭(write amplification)을 일으킬 수 있습니다. 대규모 데이터셋에서는 이로 인해 디스크 I/O가 크게 치솟고 전체 클러스터 성능이 저하될 수 있습니다. 머지(merge)와 달리 뮤테이션은 한번 제출되면 롤백할 수 없고, 명시적으로 취소하지 않는 한 서버가 재시작된 뒤에도 계속 실행됩니다. 자세한 내용은 KILL MUTATION을 참고하세요.

활성 또는 대기 중인 뮤테이션 수 모니터링하기 활성 또는 대기 중인 뮤테이션 수를 모니터링하는 방법은 다음 지식 베이스 문서를 참고하세요.

뮤테이션은 전체 순서가 보장됩니다(total ordered) : 뮤테이션이 발행되기 전에 삽입된 데이터에 적용되며, 더 새로운 데이터는 영향을 받지 않습니다. 뮤테이션은 삽입을 막지 않지만 다른 진행 중인 쿼리와 겹칠 수는 있습니다. 뮤테이션 실행 중 실행되는 SELECT는 뮤테이션된 파트와 안 된 파트를 섞어 읽을 수 있어, 실행 중 일관성 없는 데이터 뷰를 볼 수 있습니다. ClickHouse는 파트별로 뮤테이션을 병렬로 실행하므로, 특히 x IN (SELECT …) 같은 복잡한 서브쿼리가 포함된 경우 메모리와 CPU 사용이 더 커질 수 있습니다. 원칙적으로 빈번하거나 대규모인 뮤테이션은 피하는 것이 좋으며, 특히 대량 트래픽이 발생하는 테이블에서는 더욱 그렇습니다. 대신 ReplacingMergeTreeCollapsingMergeTree 같은 대체 테이블 엔진을 사용하세요. 이들은 쿼리 시점이나 머지 과정에서 데이터 수정을 더 효율적으로 처리하도록 설계되었습니다. 뮤테이션이 꼭 필요하다면 system.mutations 테이블로 신중하게 모니터링하고, 프로세스가 멈추거나 오작동하면 KILL MUTATION을 사용하세요. 뮤테이션을 잘못 사용하면 성능 저하, 과도한 저장소 소모, 서비스 불안정까지 초래할 수 있으므로 주의하고 아껴서 사용해야 합니다. 데이터 삭제가 필요하다면 가벼운 삭제(Lightweight deletes)파티션 관리를 통한 삭제 방식도 고려할 수 있습니다. 파티션을 이용하면 전체 파트를 효율적으로 drop할 수 있거든요.

더 알아보기 (Learn more)