Iceberg 테이블 메타데이터
Iceberg 테이블 메타데이터
Iceberg 테이블의 상태는 메타데이터 파일에 JSON으로 저장돼요. 테이블 메타데이터가 바뀔 때마다 새 메타데이터 파일이 만들어지고, 이 파일은 원자적(atomic) 연산으로 커밋돼요. 그 덕분에 새 버전의 메타데이터가 자신이 기반이 된 버전을 교체하도록 보장되어, 테이블 버전의 선형적인 이력을 만들고 동시 쓰기가 유실되지 않도록 해요.
본문
테이블 메타데이터 필드
테이블 메타데이터는 다음 필드로 구성돼요:
| v1 | v2 | v3 | 필드 | 설명 |
|---|---|---|---|---|
| required | required | required | format-version |
포맷의 정수 버전 번호. 구현은 테이블 버전이 지원 버전보다 높으면 예외를 던져야 해요. |
| optional | required | required | table-uuid |
테이블 생성 시 만들어진, 테이블을 식별하는 UUID. 메타데이터 새로고침 후 UUID가 예상과 다르면 예외를 던져야 해요. |
| required | required | required | location |
테이블의 기본 위치. 라이터가 데이터·매니페스트·메타데이터 파일을 어디에 저장할지 정하는 데 써요. |
| required | required | last-sequence-number |
테이블이 부여한 가장 높은 시퀀스 번호. 테이블 스냅샷 순서를 추적하는 단조 증가 long. | |
| required | required | required | last-updated-ms |
unix epoch 기준 밀리초 단위 테이블 최종 갱신 시각. 각 메타데이터 파일은 쓰기 직전에 이 필드를 갱신해야 해요. |
| required | required | required | last-column-id |
테이블에 부여된 가장 높은 컬럼 ID(정수). 스키마 진화 시 컬럼에 항상 쓰이지 않은 ID가 부여되도록 보장해요. |
| required | schema |
테이블의 현재 스키마. (Deprecated: schemas와 current-schema-id 사용) |
||
| optional | required | required | schemas |
schema-id를 가진 객체로 저장된 스키마 목록. |
| optional | required | required | current-schema-id |
테이블의 현재 스키마 ID. |
| required | partition-spec |
필드만 저장된 테이블의 현재 파티션 스펙. (Deprecated: partition-specs·default-spec-id 사용) 라이터가 데이터를 파티셔닝하는 데 쓰지만, 읽기는 매니페스트 파일에 저장된 스펙을 쓰므로 읽기에는 사용되지 않아요. |
||
| optional | required | required | partition-specs |
전체 파티션 스펙 객체로 저장된 파티션 스펙 목록. |
| optional | required | required | default-spec-id |
라이터가 기본으로 써야 하는 "현재" 스펙의 ID. |
| optional | required | required | last-partition-id |
테이블의 모든 파티션 스펙에서 부여된 가장 높은 파티션 필드 ID(정수). 스펙 진화 시 파티션 필드에 항상 쓰이지 않은 ID가 부여되도록 보장해요. |
| optional | optional | optional | properties |
테이블 속성의 문자열-문자열 맵. 읽기·쓰기에 영향을 주는 설정을 제어하며 임의 메타데이터용이 아니에요. 예: commit.retry.num-retries는 커밋 재시도 횟수를 제어해요. |
| optional | optional | optional | current-snapshot-id |
현재 테이블 스냅샷의 long ID. refs의 main 브랜치 현재 ID와 같아야 해요. |
| optional | optional | optional | snapshots |
유효한 스냅샷 목록. 유효한 스냅샷은 모든 데이터 파일이 파일 시스템에 존재하는 스냅샷이에요. 데이터 파일은 마지막으로 나열된 스냅샷이 가비지 컬렉션되기 전까지 파일 시스템에서 삭제되면 안 돼요. |
| optional | optional | optional | snapshot-log |
테이블 current 스냅샷의 변경을 인코딩하는 타임스탬프와 스냅샷 ID 쌍 목록(옵션). current-snapshot-id가 바뀔 때마다 last-updated-ms와 새 current-snapshot-id로 새 항목을 추가해야 해요. 만료된 스냅샷보다 앞선 항목은 제거해야 해요. |
| optional | optional | optional | metadata-log |
이전 메타데이터 파일 변경을 인코딩하는 타임스탬프와 메타데이터 파일 위치 쌍 목록(옵션). 새 메타데이터 파일이 만들어질 때마다 이전 메타데이터 파일 위치의 새 항목을 추가해야 해요. 커밋 후 가장 오래된 로그를 제거하고 최근 항목의 고정 크기 로그를 유지하도록 테이블을 설정할 수 있어요. |
| optional | required | required | sort-orders |
전체 정렬 순서 객체로 저장된 정렬 순서 목록. |
| optional | required | required | default-sort-order-id |
테이블의 기본 정렬 순서 id. 라이터가 쓸 수 있지만 읽기는 매니페스트에 저장된 스펙을 쓰므로 읽기에는 사용되지 않아요. |
| optional | optional | refs |
스냅샷 레퍼런스 맵. 키는 테이블의 고유한 스냅샷 레퍼런스 이름, 값은 스냅샷 레퍼런스 객체예요. refs 맵이 null이어도 current-snapshot-id를 가리키는 main 브랜치 참조는 항상 있어요. |
|
| optional | optional | optional | statistics |
테이블 통계 목록(옵션). |
| optional | optional | optional | partition-statistics |
파티션 통계 목록(옵션). |
| required | next-row-id |
부여된 모든 행 ID보다 높은 long. 다음 스냅샷의 first-row-id예요. |
||
| optional | encryption-keys |
테이블 암호화에 쓰이는 암호화 키 목록(옵션). |
메타데이터 로그와 스냅샷 로그
Iceberg 테이블은 두 종류의 로그를 메타데이터에 남겨요.
metadata-log— 이전 메타데이터 파일들의 위치를 보관하는 로그예요. 새 메타데이터 파일이 커밋될 때마다 이전 파일 위치 항목이 추가되죠. 이 로그 덕분에 테이블의 과거 메타데이터 위치를 추적할 수 있어요. 커밋 후 가장 오래된 항목을 제거하고 최근 항목의 고정 크기 로그를 유지하도록 설정할 수도 있어요.snapshot-log— current 스냅샷이 어떻게 바뀌었는지를last-updated-ms와 새current-snapshot-id의 쌍으로 기록해요. current-snapshot-id가 바뀔 때마다 새 항목을 추가해야 하고, 유효한 스냅샷 목록에서 스냅샷이 만료되면 그보다 앞선 항목은 제거해야 해요.
타임트래블 같은 point-in-time 읽기는 이 snapshot-log 메타데이터를 사용해 특정 시점의 테이블 상태를 찾아요.
테이블 통계 (Table Statistics)
테이블 통계 파일은 유효한 Puffin 파일이에요. 통계는 정보 제공용이라 리더가 무시할 수 있고, 테이블을 올바르게 읽는 데 통계 지원이 필수는 아니에요. 한 테이블이 서로 다른 스냅샷과 연결된 여러 통계 파일을 가질 수 있어요. statistics 메타데이터 필드 안의 통계 파일 메타데이터는 스냅샷 ID, 통계 경로, 파일 크기, Puffin 푸터 크기, blob 메타데이터 목록을 담는 struct로 정의돼요.
파티션 통계 (Partition Statistics)
파티션 통계 파일은 파티션 통계 파일 스펙에 기반해요. 파티션 통계는 읽기·계획에 필수가 아니고 리더가 무시할 수 있어요. 각 테이블 스냅샷은 최대 하나의 파티션 통계 파일과 연결될 수 있어요. 파일은 쓰기 연산마다 선택적으로 쓰거나, 요청 시(on demand) 계산할 수도 있어요. 리더에게 유효한 통계 파일로 간주되려면 파티션 통계 파일이 테이블 메타데이터 파일에 등록되어야 해요.
파티션 통계 파일의 파티션 데이터 튜플 스키마는 테이블에 있던 적이 있는 모든 필드의 합집합으로, 필드 id 오름차순으로 정렬돼요. 예를 들어 spec#0이 {field#1, field#2}를 갖고 테이블이 {field#1, field#2, field#3}을 가진 spec#1로 진화했다면, 통합 파티션 타입은 Struct<field#1, field#2, field#3>처럼 보여요.
total_record_count(파티션의 정확한 레코드 수)는 delete가 있는 테이블에서는 데이터 읽기가 필요할 수 있어요. 그런 경우 구현은 이 필드를 생략하고 NULL을 써서 정확한 수를 모른다는 걸 나타낼 수 있어요. delete가 없거나 삭제 벡터만 있으면 매니페스트 메타데이터로 이 필드를 채우는 게 권장돼요.