ClickHouse 백업 및 복원(Backup and Restore)

ClickHouse 백업 및 복원(Backup and Restore)

백업과 복원은 하드웨어 실패가 아닌 사람의 실수로부터 데이터를 보호하는 핵심 전략입니다. 이 문서는 ClickHouse 백업·복원 전반을 다루며, 백업 유형, 동기/비동기, 압축, 명령 요약과 설정을 설명할게요.

출처: 문서

본문

이 섹션은 ClickHouse의 백업과 복원을 폭넓게 다룹니다. 각 백업 방법에 대한 더 자세한 설명은 사이드바의 특정 방법 페이지를 참고하세요.

소개

복제(replication)는 하드웨어 실패로부터 보호하지만, 사람의 실수로부터는 보호하지 못합니다: 데이터의 우발적 삭제, 잘못된 테이블이나 잘못된 클러스터의 테이블 삭제, 잘못된 데이터 처리나 데이터 손상을 초래하는 소프트웨어 버그 같은 것들입니다. 많은 경우 이런 실수는 모든 복제본에 영향을 줍니다. ClickHouse는 일부 유형의 실수를 방지하는 내장 안전장치가 있습니다. 예를 들어 기본적으로 50 Gb를 초과하는 데이터가 있는 MergeTree 계열 엔진 테이블은 그냥 drop할 수 없습니다. 하지만 이러한 안전장치가 모든 가능한 경우를 다루지는 않으며 문제는 여전히 발생할 수 있습니다. 사람의 실수를 효과적으로 완화하려면 데이터 백업과 복원 전략을 사전에 신중하게 준비해야 합니다. 각 회사마다 사용 가능한 리소스와 비즈니스 요구 사항이 다르므로, 모든 상황에 맞는 보편적인 ClickHouse 백업·복원 솔루션은 없습니다. 1기가바이트의 데이터에 맞는 것이 수십 페타바이트의 데이터에는 맞지 않을 것입니다. 각각 장단점이 있는 다양한 접근 방식이 있으며, 이 문서 섹션에서 소개합니다. 여러 접근 방식을 하나만이 아니라 함께 사용하여 각자의 다양한 단점을 보완하는 것이 좋습니다.

백업해 두고 복원을 한 번도 시도하지 않았다면, 실제로 필요할 때 복원이 제대로 동작하지 않을 가능성이 높습니다(적어도 비즈니스가 허용하는 것보다 오래 걸릴 것입니다). 따라서 어떤 백업 방식을 선택하든 복원 과정도 자동화하고, 여유 ClickHouse 클러스터에서 정기적으로 연습하세요.

다음 페이지들은 ClickHouse에서 사용 가능한 다양한 백업·복원 방법을 자세히 설명합니다:

페이지 설명
로컬 디스크 또는 S3 디스크를 사용한 백업/복원 로컬 디스크 또는 S3 디스크로/에서 백업/복원 상세
S3 엔드포인트를 사용한 백업/복원 S3 엔드포인트로/에서 백업/복원 상세
AzureBlobStorage를 사용한 백업/복원 Azure blob storage로/에서 백업/복원 상세
대체 방법 대체 백업 방법 논의
스냅샷 백업 클라우드 오브젝트 스토리지를 사용하는 SharedMergeTree 테이블용 경량 스냅샷

백업은:

  • 전체 또는 증분일 수 있습니다
  • 동기 또는 비동기일 수 있습니다
  • 동시 또는 비동시일 수 있습니다
  • 압축 또는 비압축일 수 있습니다
  • 네임드 컬렉션을 사용할 수 있습니다
  • 비밀번호로 보호될 수 있습니다
  • 시스템 테이블, 로그 테이블, 또는 접근 관리 테이블에 대해 만들 수 있습니다

백업 유형

백업은 전체(full) 또는 증분(incremental)일 수 있습니다. 전체 백업은 데이터의 완전한 복사본인 반면, 증분 백업은 마지막 전체 백업 이후의 데이터 델타입니다. 전체 백업은 단순하고 (다른 백업과) 독립적이며 신뢰할 수 있는 복구 방법이라는 장점이 있습니다. 그러나 완료에 오래 걸릴 수 있고 공간을 많이 소비할 수 있습니다. 반면 증분 백업은 시간과 공간 모두에서 더 효율적이지만, 데이터를 복원하려면 모든 백업이 사용 가능해야 합니다. 필요에 따라 다음을 사용할 수 있습니다:

  • 전체 백업 은 더 작은 데이터베이스나 중요 데이터에 사용
  • 증분 백업 은 더 큰 데이터베이스나 백업을 자주·비용 효율적으로 해야 할 때 사용
  • 둘 다, 예를 들어 주간 전체 백업과 일일 증분 백업

동기 vs 비동기 백업

BACKUPRESTORE 명령은 ASYNC로 표시할 수도 있습니다. 이 경우 백업 명령은 즉시 반환되고 백업 프로세스는 백그라운드에서 실행됩니다. 명령이 ASYNC로 표시되지 않으면 백업 프로세스는 동기적이며 백업이 완료될 때까지 명령이 차단됩니다.

동시 vs 비동시 백업

기본적으로 ClickHouse는 동시 백업과 복원을 허용합니다. 즉 여러 백업 또는 복원 작업을 동시에 시작할 수 있습니다. 그러나 이 동작을 허용하지 않는 서버 수준 설정이 있습니다. 이 설정들을 false로 설정하면 클러스터에서 한 번에 하나의 백업 또는 복원 작업만 실행될 수 있습니다. 이는 작업 간 리소스 경합이나 잠재적 충돌을 피하는 데 도움이 됩니다. 동시 백업/복원을 허용하지 않으려면 다음 설정들을 각각 사용할 수 있습니다:

<clickhouse>
    <backups>
        <allow_concurrent_backups>false</allow_concurrent_backups>
        <allow_concurrent_restores>false</allow_concurrent_restores>
    </backups>
</clickhouse>

둘 다 기본값은 true이므로 기본적으로 동시 백업/복원이 허용됩니다. 클러스터에서 이 설정들이 false이면 클러스터에서 한 번에 하나의 백업/복원만 실행됩니다.

압축 vs 비압축 백업

ClickHouse 백업은 compression_methodcompression_level 설정을 통해 압축을 지원합니다. 백업을 만들 때 지정할 수 있습니다:

BACKUP TABLE test.table
  TO Disk('backups', 'filename.zip')
  SETTINGS compression_method='lzma', compression_level=3

네임드 컬렉션 사용하기

네임드 컬렉션은 백업/복원 작업 전반에 걸쳐 재사용할 수 있는 키-값 쌍(S3 자격 증명, 엔드포인트, 설정 같은)을 저장할 수 있게 합니다. 다음에 도움이 됩니다:

  • 관리자 접근 권한이 없는 사용자로부터 자격 증명 숨기기
  • 복잡한 구성을 중앙에 저장해 명령 단순화
  • 작업 전반의 일관성 유지
  • 쿼리 로그에서 자격 증명 노출 방지

자세한 내용은 “네임드 컬렉션”을 참고하세요.

시스템, 로그 또는 접근 관리 테이블 백업하기

시스템 테이블도 백업·복원 워크플로우에 포함할 수 있지만, 포함 여부는 특정 사용 사례에 달려 있습니다. _log 접미사(예: query_log, part_log)가 있는 것 같은 과거 데이터를 저장하는 시스템 테이블은 다른 테이블처럼 백업하고 복원할 수 있습니다. 사용 사례가 과거 데이터 분석에 의존한다면 — 예를 들어 query_log로 쿼리 성능을 추적하거나 문제를 디버깅할 때 — 이 테이블들을 백업 전략에 포함하는 것이 좋습니다. 그러나 이 테이블들의 과거 데이터가 필요하지 않다면 백업 저장 공간을 아끼기 위해 제외할 수 있습니다. users, roles, row_policies, settings_profiles, quotas 같은 접근 관리와 관련된 시스템 테이블은 백업·복원 동안 특별한 처리를 받습니다. 이 테이블들이 백업에 포함되면 그 내용은 접근 엔티티를 만들고 구성하기 위한 동등한 SQL 문을 담은 특별한 accessXX.txt 파일로 내보내집니다. 복원 시 복원 프로세스가 이 파일들을 해석하고 SQL 명령을 다시 적용하여 사용자, 역할 및 기타 구성을 다시 만듭니다. 이 기능은 ClickHouse 클러스터의 접근 제어 구성을 클러스터의 전체 설정의 일부로 백업하고 복원할 수 있게 보장합니다. 이 기능은 SQL 명령으로 관리되는 구성(“SQL 기반 접근 제어 및 계정 관리” 참고)에서만 동작합니다. ClickHouse 서버 구성 파일(예: users.xml)에 정의된 접근 구성은 백업에 포함되지 않으며 이 방법으로 복원할 수 없습니다.

일반 구문

-- 핵심 명령
BACKUP | RESTORE 
--- 무엇을 백업/복원할지 (또는 제외할지)
TABLE [db.]table_name           [AS [db.]table_name_in_backup] |
DICTIONARY [db.]dictionary_name [AS [db.]name_in_backup] |
DATABASE database_name          [AS database_name_in_backup] |
TEMPORARY TABLE table_name      [AS table_name_in_backup] |
VIEW view_name                  [AS view_name_in_backup] |
[EXCEPT TABLES ...] |
ALL [EXCEPT {TABLES|DATABASES}...] } [,...]
--- 
[ON CLUSTER 'cluster_name']
--- 어디에서 백업하거나 복원할지
TO|FROM 
File('<path>/<filename>') | 
Disk('<disk_name>', '<path>/') | 
S3('<S3 endpoint>/<path>', '<Access key ID>', '<Secret access key>', '<extra_credentials>') |
AzureBlobStorage('<connection string>/<url>', '<container>', '<path>', '<account name>', '<account key>')
--- 추가 설정
[SETTINGS ...]
[ASYNC]

각 명령의 자세한 내용은 “명령 요약”을 참고하세요.

명령 요약

위의 각 명령은 아래에 자세히 설명됩니다:

명령 설명
BACKUP 지정된 객체의 백업 생성
RESTORE 백업에서 객체 복원
TABLE [db.]table_name [AS [db.]table_name_in_backup] 특정 테이블 백업/복원 (이름 변경 가능)
[PARTITION[S] partition_expr [,...]] 테이블의 특정 파티션만 백업/복원
DICTIONARY [db.]dictionary_name [AS [db.]name_in_backup] 딕셔너리 객체 백업/복원
DATABASE database_name [AS database_name_in_backup] 전체 데이터베이스 백업/복원 (이름 변경 가능)
TEMPORARY TABLE table_name [AS table_name_in_backup] 임시 테이블 백업/복원 (이름 변경 가능)
VIEW view_name [AS view_name_in_backup] 뷰 백업/복원 (이름 변경 가능)
[EXCEPT TABLES ...] 데이터베이스 백업 시 특정 테이블 제외
ALL 모든 것 백업/복원 (모든 데이터베이스, 테이블 등). ClickHouse 23.4 이전 버전에서는 ALLRESTORE 명령에만 적용되었습니다.
`[EXCEPT {TABLES DATABASES}...]`
[ON CLUSTER 'cluster_name'] ClickHouse 클러스터 전체에서 백업/복원 실행
`TO FROM`
File('<path>/<filename>') 로컬 파일시스템에 저장/복원
Disk('<disk_name>', '<path>/') 구성된 디스크에 저장/복원
S3('<S3 endpoint>/<path>', '<Access key ID>', '<Secret access key>') Amazon S3 또는 S3 호환 스토리지에 저장/복원
[SETTINGS ...] 전체 설정 목록은 아래 참고
[ASYNC] 작업을 비동기로 실행 (모니터링할 수 있는 ID와 함께 즉시 반환)

설정

일반 백업/복원 설정

설정 설명 기본값
id 백업 또는 복원 작업의 ID. 지정하지 않으면 무작위 생성 UUID가 사용됩니다. 같은 ID의 실행 중인 작업이 이미 있으면 예외가 발생합니다.
compression_method 백업의 압축 방법 지정. “컬럼 압축 코덱” 섹션 참고
compression_level 백업의 압축 수준 지정
password 백업 아카이브의 비밀번호. ZIP 아카이브(.zip, .zipx)에서만 지원됩니다.
base_backup 증분 백업에 사용되는 기본 백업의 대상. 예: Disk('backups', '1.zip')
use_same_password_for_base_backup 기본 백업 아카이브가 쿼리의 비밀번호를 상속할지 여부.
structure_only 활성화되면 실제 테이블 데이터 없이 CREATE 문만 백업하거나 복원합니다.
restore_table_data 테이블의 데이터를 복원할지 여부. RESTORE 명령에만 적용됩니다. 설정하지 않으면 기본값은 NOT structure_only이며, 명시적으로 설정하면 structure_only를 재정의합니다. “복원 설정” 참고.
restore_access_entities 접근 엔티티(사용자, 역할, 설정 프로필, 행 정책, 쿼터)를 복원할지 여부. RESTORE 명령에만 적용됩니다. 설정하지 않으면 기본값은 NOT structure_only이며, 명시적으로 설정하면 structure_only를 재정의합니다. “복원 설정” 참고.
restore_functions 사용자 정의 함수를 복원할지 여부. RESTORE 명령에만 적용됩니다. 설정하지 않으면 기본값은 NOT structure_only이며, 명시적으로 설정하면 structure_only를 재정의합니다. “복원 설정” 참고.
storage_policy 복원되는 테이블의 스토리지 정책. “데이터 저장에 여러 블록 디바이스 사용” 참고. RESTORE 명령에만 적용됩니다. MergeTree 계열 엔진이 있는 테이블에만 적용됩니다.
allow_non_empty_tables RESTORE TABLE이 비어 있지 않은 테이블에 데이터를 삽입할 수 있게 합니다. 테이블의 기존 데이터와 백업에서 추출한 데이터가 섞입니다. 이 설정은 테이블에서 데이터 중복을 유발할 수 있으므로 주의해서 사용하세요. 0
backup_restore_keeper_max_retries BACKUP 또는 RESTORE 작업 중간에 [Zoo]Keeper 작업에 대한 최대 재시도 수. 일시적인 [Zoo]Keeper 실패 때문에 전체 작업이 실패하지 않을 만큼 충분히 커야 합니다. 1000
backup_restore_keeper_retry_initial_backoff_ms 백업 또는 복원 중 [Zoo]Keeper 작업의 초기 백오프 타임아웃 100
backup_restore_keeper_retry_max_backoff_ms 백업 또는 복원 중 [Zoo]Keeper 작업의 최대 백오프 타임아웃 5000
backup_restore_failure_after_host_disconnected_for_seconds BACKUP ON CLUSTER 또는 RESTORE ON CLUSTER 작업 중 호스트가 이 시간 동안 일시적 'alive' 노드를 ZooKeeper에 다시 만들지 않으면 전체 백업 또는 복원이 실패한 것으로 간주됩니다. 이 값은 호스트가 실패 후 ZooKeeper에 다시 연결하는 합리적인 시간보다 커야 합니다. 0은 무제한을 의미합니다. 3600
backup_restore_keeper_max_retries_while_initializing BACKUP ON CLUSTER 또는 RESTORE ON CLUSTER 작업 초기화 중 [Zoo]Keeper 작업의 최대 재시도 수. 20
backup_restore_keeper_max_retries_while_handling_error BACKUP ON CLUSTER 또는 RESTORE ON CLUSTER 작업의 오류를 처리하는 동안 [Zoo]Keeper 작업의 최대 재시도 수. 20
backup_restore_finish_timeout_after_error_sec 개시자가 다른 호스트가 'error' 노드에 반응하고 현재 BACKUP ON CLUSTER 또는 RESTORE ON CLUSTER 작업을 멈추기를 기다리는 시간. 180
backup_restore_keeper_value_max_size 백업 중 [Zoo]Keeper 노드 데이터의 최대 크기 1048576
backup_restore_batch_size_for_keeper_multi 백업 또는 복원 중 [Zoo]Keeper에 대한 다중 요청의 최대 배치 크기 1000
backup_restore_batch_size_for_keeper_multiread 백업 또는 복원 중 [Zoo]Keeper에 대한 다중 읽기 요청의 최대 배치 크기 10000
backup_restore_keeper_fault_injection_probability 백업 또는 복원 중 keeper 요청의 대략적 실패 확률. 유효 값은 [0.0f, 1.0f] 구간 0
backup_restore_keeper_fault_injection_seed 무작위 시드의 경우 0, 그렇지 않으면 설정 값 0
backup_restore_s3_retry_attempts Aws::Client::RetryStrategy 설정. Aws::Client는 자체적으로 재시도하며, 0은 재시도 없음을 의미합니다. 백업/복원에만 적용됩니다. 1000
max_backup_bandwidth 서버의 특정 백업에 대한 최대 읽기 속도(초당 바이트). 0은 무제한 의미. 0
max_backups_io_thread_pool_size ClickHouse는 Backups IO Thread 풀의 스레드를 사용해 S3 백업 IO 작업을 수행합니다. max_backups_io_thread_pool_size는 풀의 최대 스레드 수를 제한합니다. 1000
max_backups_io_thread_pool_free_size Backups IO Thread 풀의 유휴 스레드 수가 max_backup_io_thread_pool_free_size를 초과하면 ClickHouse는 유휴 스레드가 차지하는 리소스를 해제하고 풀 크기를 줄입니다. 필요하면 스레드를 다시 만들 수 있습니다. 0
backups_io_thread_pool_queue_size Backups IO Thread 풀에 스케줄될 수 있는 최대 작업 수. 현재 S3 백업 논리 때문에 이 큐를 무제한으로 유지하는 것이 좋습니다. 참고: 0(기본값)은 무제한을 의미합니다. 0
backup_threads BACKUP 요청을 실행할 최대 스레드 수.
max_backup_bandwidth_for_server 서버의 모든 백업에 대한 최대 읽기 속도(초당 바이트). 0은 무제한 의미. 0
shutdown_wait_backups_and_restores true로 설정하면 ClickHouse는 종료 전에 실행 중인 백업과 복원이 끝나기를 기다립니다. 1

S3 특정 설정

설정 설명 기본값
use_same_s3_credentials_for_base_backup S3로의 기본 백업이 쿼리에서 자격 증명을 상속할지 여부. S3에서만 동작합니다.
s3_storage_class S3 백업에 사용되는 스토리지 클래스. 예: STANDARD

Azure 특정 설정

설정 설명 기본값
azure_attempt_to_create_container Azure Blob Storage 사용 시, 지정된 컨테이너가 없으면 만들기를 시도할지 여부. true

관리 및 문제 해결

백업 명령은 idstatus를 반환하며, 그 id로 백업의 상태를 얻을 수 있습니다. 이것은 긴 ASYNC 백업의 진행을 확인하는 데 매우 유용합니다. 아래 예제는 기존 백업 파일을 덮어쓰려 할 때 발생한 실패를 보여줍니다:

BACKUP TABLE helloworld.my_first_table TO Disk('backups', '1.zip') ASYNC
┌─id───────────────────────────────────┬─status──────────┐
│ 7678b0b3-f519-4e6e-811f-5a0781a4eb52 │ CREATING_BACKUP │
└──────────────────────────────────────┴─────────────────┘

1 row in set. Elapsed: 0.001 sec.
SELECT
*
FROM system.backups
WHERE id='7678b0b3-f519-4e6e-811f-5a0781a4eb52'
FORMAT Vertical
Row 1:
──────
id:                7678b0b3-f519-4e6e-811f-5a0781a4eb52
name:              Disk('backups', '1.zip')
status:            BACKUP_FAILED
num_files:         0
uncompressed_size: 0
compressed_size:   0
error:             Code: 598. DB::Exception: Backup Disk('backups', '1.zip') already exists. (BACKUP_ALREADY_EXISTS) (version 22.8.2.11 (official build))
start_time:        2022-08-30 09:21:46
end_time:          2022-08-30 09:21:46

1 row in set. Elapsed: 0.002 sec.

system.backups 테이블과 함께 모든 백업 및 복원 작업은 시스템 로그 테이블 system.backup_log에도 추적됩니다:

SELECT *
FROM system.backup_log
WHERE id = '7678b0b3-f519-4e6e-811f-5a0781a4eb52'
ORDER BY event_time_microseconds ASC
FORMAT Vertical
Row 1:
──────
event_date:              2023-08-18
event_time_microseconds: 2023-08-18 11:13:43.097414
id:                      7678b0b3-f519-4e6e-811f-5a0781a4eb52
name:                    Disk('backups', '1.zip')
status:                  CREATING_BACKUP
error:
start_time:              2023-08-18 11:13:43
end_time:                1970-01-01 03:00:00
num_files:               0
total_size:              0
num_entries:             0
uncompressed_size:       0
compressed_size:         0
files_read:              0
bytes_read:              0

Row 2:
──────
event_date:              2023-08-18
event_time_microseconds: 2023-08-18 11:13:43.174782
id:                      7678b0b3-f519-4e6e-811f-5a0781a4eb52
name:                    Disk('backups', '1.zip')
status:                  BACKUP_FAILED
error:                   Code: 598. DB::Exception: Backup Disk('backups', '1.zip') already exists. (BACKUP_ALREADY_EXISTS) (version 23.8.1.1)
start_time:              2023-08-18 11:13:43
end_time:                2023-08-18 11:13:43
num_files:               0
total_size:              0
num_entries:             0
uncompressed_size:       0
compressed_size:         0
files_read:              0
bytes_read:              0

2 rows in set. Elapsed: 0.075 sec.

더 알아보기 (Learn more)