LabHub
学习 学习路径 课程

ClickHouse — 열 지향 분석 DB 를 속까지 · ReplacingMergeTree · 实验

병합 전의 중복을 보고, FINAL·argMax·CLEANUP 으로 다룬다

在 LabHub 中继续学习

목표

ReplacingMergeTree 에 변경 기록(갱신·탈퇴)을 넣고, 병합 전에는 옛 버전이 보인다는 것과 그것을 FINAL·argMax 로 가리는 법, 병합과 CLEANUP 이 실제로 무엇을 지우는지, 정렬 키와 재전송이 결과를 어떻게 바꾸는지 숫자로 확인합니다.

왜 중요한가

분석 DB 로 옮긴 운영 데이터는 계속 바뀝니다. ClickHouse 는 갱신을 "새 버전 INSERT + 나중 병합" 으로 처리하는데, 병합은 언제 일어날지 모릅니다. 그래서 같은 쿼리가 어떤 때는 맞고 어떤 때는 틀립니다. 이 실습은 SYSTEM STOP MERGES 로 "병합 전" 을 고정해 그 틀린 답을 눈으로 보고, 조회 시점에 맞는 답을 내는 두 방법을 익힙니다. 채점기는 기대값을 원본 생성 식에서 직접 계산하고, 병합이 실제로 일어났는지는 system.part_log 의 기록으로 확인합니다.

단계

1. 데이터베이스 rmt 와 표 rmt.users 를 만드세요 — 열 user_id UInt64, email String, plan LowCardinality(String), score UInt32, ver UInt32, is_deleted UInt8(이 순서), 엔진 ReplacingMergeTree(ver, is_deleted), ORDER BY user_id.
2. SYSTEM STOP MERGES rmt.users 로 이 표의 병합을 멈춘 뒤 /opt/lab/fixtures/replacing/changes.sql한 번 실행하세요(INSERT 세 번 = 파트 세 개).
3. FINAL 없이 전체 행을 세는 /root/ch/replacing/q_raw.sqlFROM rmt.users FINAL 로 세는 /root/ch/replacing/q_final.sql 을 만들고, 두 결과를 /root/ch/replacing/counts.jsonraw·final 로 적으세요.
4. FINAL 을 쓰지 않고 요금제(plan)별 현재 사용자 수를 내는 /root/ch/replacing/q_plan.sql 을 만드세요 — 결과는 plan 과 사용자 수 두 열입니다.
5. rmt.mergedrmt.users 와 같은 열·엔진으로 만들어 rmt.users 의 행을 ver = 1, ver = 2, ver = 3 순으로 INSERT 세 번에 옮기고 OPTIMIZE TABLE rmt.merged FINAL 을 실행한 뒤, rows_after_merge(count())·deleted_rows_kept(is_deleted = 1 인 행 수)·final_count(FINAL 로 센 수)를 /root/ch/replacing/merged.json 에 적으세요.
6. rmt.cleaned 를 같은 열·엔진에 표 설정 allow_experimental_replacing_merge_with_cleanup = 1 을 붙여 만들고, 같은 방법으로 세 번 넣은 뒤 OPTIMIZE TABLE rmt.cleaned FINAL CLEANUP 을 실행해 rows_after_cleanup·deleted_rows_left/root/ch/replacing/cleanup.json 에 적으세요.
7. 같은 열·엔진이지만 정렬 키가 ORDER BY (user_id, plan)rmt.bad 를 만들어 같은 방법으로 세 번 넣고 OPTIMIZE TABLE rmt.bad FINAL 한 뒤, good_final(rmt.merged 를 FINAL 로 센 수)·bad_final(rmt.bad 를 FINAL 로 센 수)·bad_users(rmt.bad FINAL 의 서로 다른 user_id 수)를 /root/ch/replacing/key.json 에 적으세요.
8. 늦은 재전송을 흉내 냅니다 — rmt.users 에서 ver = 1 AND user_id <= 1000 인 행을 rmt.mergedrmt.cleaned 에 각각 다시 넣고, 두 표를 FINAL 로 센 값과 그 차이를 /root/ch/replacing/replay.jsonmerged_final·cleaned_final·resurrected 로 적으세요.

참고

8个步骤

  1. 버전과 삭제 표시가 있는 표
  2. 병합을 멈추고 변경 기록 세 묶음을 넣는다
  3. FINAL 없이 세기와 FINAL 로 세기
  4. FINAL 없이 같은 답 — argMax
  5. 병합해도 탈퇴 행은 남는다
  6. CLEANUP 병합은 탈퇴 행까지 지운다
  7. 정렬 키가 "같은 행" 을 정한다
  8. CLEANUP 뒤에 옛 행이 다시 오면