ALTER 문

ALTER 문

이 페이지에서는 ClickHouse의 ALTER 문에 대한 전반적인 내용을 다뤄요. ALTER TABLE 쿼리가 테이블 설정이나 데이터를 어떻게 수정하는지, 변경(mutation) 메커니즘, 그리고 동기화 방식에 대해 설명해요.

출처: 문서

본문

대부분의 ALTER TABLE 쿼리는 테이블 설정이나 데이터를 수정해요:

대부분의 ALTER TABLE 쿼리는 *MergeTree, Merge, Distributed 테이블에서만 지원돼요. 다음 ALTER 문은 뷰를 조작해요:

다음 ALTER 문은 역할 기반 접근 제어와 관련된 엔티티를 수정해요:

변경 (Mutations)

테이블 데이터를 조작하려는 ALTER 쿼리는 "변경(mutations)"이라는 메커니즘으로 구현돼요. 가장 대표적인 것은 ALTER TABLE … DELETEALTER TABLE … UPDATE예요. 이것들은 MergeTree 테이블의 병합과 유사한 비동기 백그라운드 프로세스로, 파츠의 새 "변경된" 버전을 만들기 위해 실행돼요. *MergeTree 테이블의 변경은 전체 데이터 파츠를 다시 작성하여 실행돼요. 원자성이 없어요 — 파츠는 준비되는 즉시 변경된 파츠로 대체되며, 변경 중에 실행을 시작한 SELECT 쿼리는 이미 변경된 파츠의 데이터와 아직 변경되지 않은 파츠의 데이터를 함께 보게 돼요. 변경은 생성 순서에 따라 완전히 정렬되며 각 파츠에 그 순서로 적용돼요. 변경은 INSERT INTO 쿼리와 부분적으로도 정렬돼요: 변경이 제출되기 전에 테이블에 삽입된 데이터는 변경되고, 그 후에 삽입된 데이터는 변경되지 않아요. 변경이 삽입을 어떤 식으로든 차단하지 않는다는 점에 유의해요. 변경 쿼리는 변경 항목이 추가된 직후에 반환돼요(복제 테이블의 경우 ZooKeeper에, 비복제 테이블의 경우 파일시스템에). 변경 자체는 시스템 프로필 설정을 사용해 비동기로 실행돼요. 변경 진행 상황을 추적하려면 system.mutations 테이블을 사용할 수 있어요. 성공적으로 제출된 변경은 ClickHouse 서버가 재시작되어도 계속 실행돼요. 제출된 변경을 롤백할 방법은 없지만, 어떤 이유로 변경이 멈추면 KILL MUTATION 쿼리로 취소할 수 있어요. 완료된 변경의 항목은 즉시 삭제되지 않아요(유지되는 항목 수는 finished_mutations_to_keep 스토리지 엔진 매개변수로 결정). 더 오래된 변경 항목은 삭제돼요.

ALTER 쿼리의 동기성

비복제 테이블의 경우 모든 ALTER 쿼리는 동기적으로 수행돼요. 복제 테이블의 경우 쿼리는 적절한 작업에 대한 지침을 ZooKeeper에 추가할 뿐이며, 작업 자체는 가능한 한 빨리 수행돼요. 하지만 쿼리는 모든 레플리카에서 이 작업이 완료되기를 기다릴 수 있어요. 변경을 만드는 ALTER 쿼리(예: UPDATE, DELETE, MATERIALIZE INDEX, MATERIALIZE PROJECTION, MATERIALIZE COLUMN, APPLY DELETED MASK, APPLY PATCHES, CLEAR STATISTIC, MATERIALIZE STATISTIC 등에 한정되지 않음)의 경우 동기성은 mutations_sync 설정으로 정의돼요. 메타데이터만 수정하는 다른 ALTER 쿼리의 경우 alter_sync 설정으로 대기 방식을 설정할 수 있어요. 비활성 레플리카가 모든 ALTER 쿼리를 실행하기를 얼마나(초) 기다릴지 replication_wait_for_inactive_replica_timeout 설정으로 지정할 수 있어요. 모든 ALTER 쿼리에 대해 alter_sync = 2이고 일부 레플리카가 replication_wait_for_inactive_replica_timeout 설정에 지정된 시간보다 더 오래 비활성이면 UNFINISHED 예외가 발생해요. alter_sync = 3에서는 비활성 레플리카를 기다리지 않으므로 예외가 발생하지 않아요.

한 테이블에 대한 동시 ALTER 할당

복제 테이블에서 같은 테이블에 대해 여러 개의 개별 ALTER 문을 빠르게 연속으로 제출하면 CANNOT_ASSIGN_ALTER(코드 517)로 실패할 수 있어요. 복제 경로는 레플리카가 일부 이전 ALTER를 아직 적용하지 않았을 때(메타데이터 버전이 여전히 공통 메타데이터보다 뒤처짐 — 서버가 "다음 중 일부 이전 alter를 아직 적용하지 않음" 또는 "동시에 너무 많은 alter가 실행 중일 수 있음"이라고 말할 수 있음) 이것을 발생시켜요. 이 조건은 이전 ALTER가 이미 할당된 후에도 여전히 참일 수 있어요. 이것은 일반적인 동시 메타데이터-ALTER / 변경 조건이며, 변경 전용 문에만 국한되지 않아요. 일반적인 동시 메타데이터 alter(ADD/DROP/MODIFY 등)도 같은 재시도 가능 코드를 발생시킬 수 있어요(참고: tests/queries/0_stateless/03518_alter_logical_race.sh가 다루는 재시도 경로). 경쟁을 피하는 접근 방식:

  • 문법이 허용할 때 독립적인 메타데이터 작업을 단일 다중 절 ALTER로 결합해요(예: 여러 ADD INDEX 절).

  • ALTER 문을 직렬화하고 코드 517에서 이전 ALTER가 레플리카에 적용될 때까지 재시도해요.

  • 변경을 만드는 ALTER의 경우, 다음 것을 제출하기 전에 mutations_syncsystem.mutationsis_done 같은 문서화된 관찰 수단으로 이전 변경이 끝나기를 기다려요.

MATERIALIZE INDEX 절 결합

하나의 ALTER에 여러 MATERIALIZE INDEX 절이 나타날 수 있어요. 트리에서 다루는 경우는 동일한 문에서 여러 ADD INDEX 절을 그 새 인덱스에 대한 MATERIALIZE INDEX와 함께 묶는 것이에요(참고: tests/queries/0_stateless/02911_add_index_and_materialize_index.sql). 그것은 AlterCommand 세그먼트와 MutationCommand 세그먼트를 섞으므로 DatabaseReplicated가 QUERY_IS_PROHIBITED로 거부해요(InterpreterAlterQuery::validateReplicatedDatabaseSegments). 02911 예시는 일반(비-DatabaseReplicated) 데이터베이스에서 유효한 것으로 취급하세요. DatabaseReplicated에서는 메타데이터 변경과 materialize 변경을 별도의 문으로 유지하세요. 현재 구현에서 각 MATERIALIZE INDEX 절은 변경이 준비될 때 테이블 메타데이터 스냅샷에 대해 해석되므로, 이미 존재하는 인덱스에 대한 materialize 전용 다중 절 형태는 같은 준비 경로(변경 전용이므로 한 세그먼트 안에 남음)를 따라요. 그 정확한 모양은 아직 집중된 stateless 테스트로 다뤄지지 않았어요. 그러한 커버리지가 생길 때까지 그것을 별도로 보장된 계약보다는 현재 구현 동작으로 취급해요. 정렬된 변경 적용이 필요하면 여전히 문당 하나의 MATERIALIZE INDEX를 발행하고 mutations_sync로 기다릴 수 있어요.

관련 콘텐츠

더 알아보기 (Learn more)