스냅샷 백업 및 복원(Snapshot Backup and Restore)
스냅샷 백업 및 복원(Snapshot Backup and Restore)
스냅샷 백업은 클라우드 네이티브 테이블 엔진을 위한 경량 백업 모드입니다. 데이터를 복사하는 대신 파트별 락 노드를 ClickHouse Keeper에 써서, 스냅샷이 유지되는 동안 참조된 오브젝트 스토리지 파츠가 삭제되지 않게 막습니다. 이 문서에서는 스냅샷 생성, 복원, 잠금 해제와 관측 방법을 설명할게요.
출처: 문서
본문
스냅샷 백업은 클라우드 네이티브 테이블 엔진을 위한 경량 백업 모드입니다. 데이터를 복사하는 대신 파트별 락 노드를 ClickHouse Keeper에 기록합니다. 이 락들은 스냅샷이 유지되는 동안 서버가 참조된 오브젝트 스토리지 파츠를 삭제하지 못하게 합니다. 그런 다음 백업은 데이터를 물리적으로 복사하지 않고 오브젝트 스토리지 참조를 기록하므로, 테이블 크기와 관계없이 스냅샷 생성이 빠릅니다. 이 경량 경로는 SharedMergeTree, SharedSet, SharedJoin 테이블에 적용됩니다. Log나 Memory 같은 다른 모든 엔진 타입의 경우 백업은 자동으로 표준 복사 기반 백업으로 폴백합니다.
스냅샷 생성하기
스냅샷 백업은 experimental_lightweight_snapshot = true와 함께 표준 BACKUP 명령을 사용합니다. id 설정이 필요합니다 — 스냅샷의 이름을 지정하며 잠금 해제 및 관측 명령에서 참조하는 데 사용됩니다:
BACKUP { TABLE [db.]table_name | DATABASE db_name | ALL [EXCEPT {TABLES | DATABASES} ...] }
TO { S3(...) | AzureBlobStorage(...) }
SETTINGS experimental_lightweight_snapshot = true, id = '<snapshot_id>'
명령은 id와 status를 반환하며, id를 사용해 system.backups에서 작업을 추적할 수 있습니다. 단일 테이블을 S3에 백업:
BACKUP TABLE mydb.events
TO S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS experimental_lightweight_snapshot = true, id = 'events_snapshot_1'
전체 데이터베이스 백업:
BACKUP DATABASE mydb
TO S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/mydb/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS experimental_lightweight_snapshot = true, id = 'mydb_snapshot_1'
하나를 제외한 모든 테이블 백업:
BACKUP ALL
EXCEPT TABLES mydb.staging_table
TO S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/full/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS experimental_lightweight_snapshot = true, id = 'full_snapshot_1'
같은 명령들이 Azure Blob Storage에서도 동작합니다:
BACKUP TABLE mydb.events
TO AzureBlobStorage('DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=...', 'my-container', 'snapshots/events/')
SETTINGS experimental_lightweight_snapshot = true, id = 'events_snapshot_1'
같은 서비스로 복원하기
스냅샷은 데이터의 복사본이 아니라 오브젝트 스토리지 파일에 대한 참조를 저장하므로, 새 서비스나 다른 ClickHouse 서비스로 복원하려면 원본 오브젝트 스토리지에 접근해야 합니다. 이런 이유로 교차 서비스 복원은 SQL을 통해서는 지원되지 않습니다 — UI에서만 사용할 수 있습니다. SQL로는 snapshot_from_current_service = 1을 사용해 외부 백업 버킷에서 같은 서비스로 스냅샷을 복원할 수 있습니다. 이것은 원격 스냅샷 리더를 통하지 않고 대상 디스크를 통해 객체를 직접 읽습니다:
RESTORE TABLE mydb.events AS mydb.events_restored
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS snapshot_from_current_service = 1
AS 절은 새 테이블 이름으로 복원하여 원본 테이블을 그대로 둡니다. 원본 테이블을 덮어쓰려면 먼저 drop 하세요:
DROP TABLE mydb.events;
RESTORE TABLE mydb.events
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS snapshot_from_current_service = 1
스냅샷 잠금 해제하기
각 스냅샷은 참조된 오브젝트 스토리지 파일이 가비지 컬렉션되지 않도록 하는 락을 ClickHouse Keeper에 보유합니다. 복원이 완료된 후 — 또는 스냅샷이 더 이상 필요하지 않을 때 — 잠금을 해제하여 이 락들을 해제하세요. 두 가지 형태가 있습니다: 스냅샷의 모든 락을 한 번에 제거하는 시스템 수준 잠금 해제와, 단일 테이블의 락만 제거하고 나머지 스냅샷은 그대로 두는 테이블별 잠금 해제입니다. 시스템 수준 잠금 해제 — 스냅샷의 모든 락을 제거합니다:
SYSTEM UNLOCK SNAPSHOT '<snapshot_id>'
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
테이블별 잠금 해제 — 한 테이블의 락만 제거합니다:
ALTER TABLE mydb.events UNLOCK SNAPSHOT '<snapshot_id>'
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
스냅샷 대상이 생성 시점에 Keeper에 저장되었다면(system.snapshot_locks의 info 컬럼에서 확인 가능) FROM 절은 선택 사항입니다:
SYSTEM UNLOCK SNAPSHOT '<snapshot_id>'
-- 또는 테이블별:
ALTER TABLE mydb.events UNLOCK SNAPSHOT '<snapshot_id>'
잠금 해제 후 해당 행은 system.snapshot_locks에서 사라지고, 다른 스냅샷이 더 이상 참조하지 않는 파츠는 system.snapshot_parts에서 빠집니다.
관측 (Observability)
system.backups
모든 스냅샷 작업은 일반 백업·복원 작업과 함께 system.backups에 나타납니다. 설정한 id(또는 명령이 반환한 UUID)로 조회하세요.
system.snapshot_locks
system.snapshot_locks는 현재 Keeper에 등록된 커밋된 스냅샷을 보여줍니다. 스냅샷이 커밋되면 /clickhouse/snapshot/committed/{snapshot_id}에 Keeper 노드가 생성됩니다. 어떤 데이터 파트를 삭제하기 전에 서버는 커밋된 스냅샷이 그 파트에 락을 보유하고 있는지 확인합니다. 락이 있으면 삭제를 건너<립니다. 락은 스냅샷을 명시적으로 잠금 해제할 때까지 유지됩니다.
| 컬럼 | 타입 | 설명 |
|---|---|---|
id |
String |
스냅샷 ID |
info |
String |
스냅샷 대상, 예: S3('...') |
ctime |
DateTime |
이 락이 Keeper에서 생성된 시각 |
lock_path |
String |
이 락의 Keeper 경로 |
각 행은 하나의 커밋된 스냅샷을 나타냅니다. 더 이상 유효한 백업 대상이 없는 스냅샷에 대한 락이 보이면 SYSTEM UNLOCK SNAPSHOT을 실행해 정리하세요. 특정 스냅샷 락이 존재하는지 확인하려면 system.snapshot_locks를 id로 조회하세요.
system.snapshot_parts
system.snapshot_parts는 현재 적어도 하나의 스냅샷 락으로 고정되어 있는 데이터 파츠를 보여줍니다. 각 락된 파츠에 대해 파츠의 압축·비압축 크기를 담은 Keeper 노드가 /clickhouse/snapshot/{table_uuid}/{part_name}에 존재합니다. 이 테이블은 그 노드들을 읽어 현재 삭제로부터 보호되는 파츠를 보여줍니다.
| 컬럼 | 타입 | 설명 |
|---|---|---|
name |
String |
데이터 파츠 이름 |
table_id |
String |
이 파츠가 속한 테이블의 UUID |
data_compressed_bytes |
UInt64 |
이 파츠의 압축 크기 |
data_uncompressed_bytes |
UInt64 |
이 파츠의 비압축 크기 |
snapshots_size |
UInt64 |
현재 이 파츠에 락을 보유한 스냅샷 수 |
snapshots_size > 1인 파츠는 여러 스냅샷이 참조하며, 보유한 모든 스냅샷이 잠금 해제될 때까지 오브젝트 스토리지에서 제거되지 않습니다. 고정된 총 저장 공간을 확인하려면 system.snapshot_parts에서 data_compressed_bytes 합계를 조회하세요.
스냅샷에 락이 걸려 있지만 이미 drop 되었거나 서버에서 더 이상 활성화되지 않은 파츠 — 즉 오직 스냅샷 락 때문에만 오브젝트 스토리지에 보관되고 있는 데이터 — 를 찾으려면 system.snapshot_parts를 system.parts와 조인하여 서버에 없는 name을 찾으면 됩니다. 이는 원본 데이터가 변경되거나 제거된 후 스냅샷을 보유하는 저장 오버헤드를 이해하는 데 유용합니다.
서버 설정
다음 서버 구성 매개변수들이 스냅샷 동작을 제어합니다. 이것들은 SQL이 아니라 서버 구성 파일에 설정됩니다.
| 설정 | 타입 | 기본값 | 재시작 없이 변경 가능 | 설명 |
|---|---|---|---|---|
max_held_snapshots |
UInt64 | 0 |
아니오 | 동시에 보유할 수 있는 경량 스냅샷의 최대 수. 0은 무제한. 한도에 도달하면 새 스냅샷 생성 시 예외가 발생합니다. |
max_snapshot_commit_thread_pool_size |
UInt64 | 64 |
예 | 스냅샷 락 노드를 Keeper에 커밋하는 데 사용되는 스레드 수. 많은 파츠를 가진 큰 테이블에서 스냅샷 생성이 느리면 증가시키세요. |
max_snapshot_commit_thread_pool_free_size |
UInt64 | 0 |
예 | 스냅샷 커밋 풀의 유휴 스레드 수가 이 값을 초과하면 ClickHouse가 그 스레드들을 해제하고 풀을 축소합니다. 스레드는 필요 시 다시 생성됩니다. 0은 유휴 스레드가 절대 해제되지 않음을 의미합니다. |
snapshot_cleaner_period |
UInt64 | 120 |
아니오 | 스냅샷 클리너가 더 이상 어떤 스냅샷 락도 참조하지 않는 파츠를 제거하기 위해 실행되는 주기(초). ClickHouse Cloud 전용. |
snapshot_cleaner_pool_size |
UInt64 | 128 |
아니오 | 스냅샷 클리너 스레드 풀의 스레드 수. ClickHouse Cloud 전용. |