Iceberg에 쓰기

Iceberg에 쓰기 (Writing to Iceberg)

DuckDB iceberg 익스텐션은 Iceberg 카탈로그가 attach되어 있을 때 Iceberg 테이블에 쓰기를 지원해요. iceberg_scan으로 스토리지에서 직접 읽은 테이블에 쓰는 것은 지원되지 않아요: 새 테이블 메타데이터를 커밋하려면 카탈로그가 필요해요.

출처: 문서

본문

지원되는 연산 (Supported Operations)

iceberg 익스텐션은 REST Catalog가 attach된 상태에서 다음 연산을 지원해요:

  • CREATE/DROP SCHEMA
  • CREATE/DROP TABLE
  • INSERT INTO
  • UPDATE
  • DELETE
  • MERGE INTO
  • ALTER TABLE
  • SELECT

이 연산들이 지원되므로 다음도 동작해요:

COPY FROM DATABASE duckdb_db TO iceberg_datalake;
-- 또는
COPY FROM DATABASE iceberg_datalake TO duckdb_db;

이 기능은 Iceberg와 DuckDB 스토리지 사이에 딥 카피를 가능하게 해요.

테이블 만들기 (Creating Tables)

테이블은 표준 CREATE TABLE 문법으로 만들어요. Iceberg 테이블 속성WITH 절로 제공할 수 있어요:

CREATE TABLE test_create_table (a INTEGER)
WITH (
    'format-version' = '2', -- 테이블을 만들 때 format-version으로 승격됨
    'location' = 's3://path/to/data', -- 테이블을 만들 때 location으로 승격됨
    'property1' = 'value1',
    'property2' = 'value2'
);

테이블 속성은 생성 후에도 조회·수정할 수 있어요. Table Properties Functions를 참고해요.

MERGE INTO

MERGE INTO 문은 기본 키가 없는 Iceberg 테이블에 대한 upsert를 표현하는 권장 방법이에요. 변경 세트를 단일 문으로 적용하고, 행마다 삽입·업데이트·삭제 여부를 결정할 수 있어요:

MERGE INTO iceberg_catalog.default.people AS target
    USING (
        FROM (VALUES
            (1, 'John', 105_000.0),
            (3, 'Sarah', 95_000.0)
        ) t(id, name, salary)
    ) AS upserts
    ON (upserts.id = target.id)
    WHEN MATCHED THEN UPDATE
    WHEN NOT MATCHED THEN INSERT;

같은 문에서 WHEN MATCHED THEN DELETE를 사용해 삭제 세트를 표현할 수도 있어요. UPDATEDELETE처럼 MERGE INTO는 merge-on-read 시맨틱을 사용하고 Iceberg 테이블에 positional deletes를 써요.

ALTER TABLE과 스키마 발전

ALTER TABLE 문은 Iceberg 테이블에서 지원되며, 가장 흔한 스키마 발전 연산을 다뤄요:

-- 테이블 이름 바꾸기
ALTER TABLE iceberg_catalog.default.simple_table
    RENAME TO renamed_table;

-- 열 추가
ALTER TABLE iceberg_catalog.default.renamed_table
    ADD COLUMN col3 DOUBLE;

-- 열 이름 바꾸기
ALTER TABLE iceberg_catalog.default.renamed_table
    RENAME COLUMN col2 TO name;

-- 열 삭제
ALTER TABLE iceberg_catalog.default.renamed_table
    DROP COLUMN col3;

-- format-version 설정
ALTER TABLE iceberg_catalog.default.renamed_table
    SET ('format-version' = 3);

ALTER TABLE 문은 Iceberg 테이블의 current-schema-id를 업데이트하며, 변경 사항은 다른 Iceberg 인식 엔진이 다음에 LoadTableInformation 엔드포인트를 조회할 때 보이게 돼요. Iceberg 스키마 발전은 메타데이터 전용이라 데이터 파일이 다시 쓰이지 않아요.

파티션 트랜스폼 (Partition Transforms)

identity 파티셔닝 외에도 DuckDB-Iceberg는 buckettruncate 파티션 트랜스폼을 사용하는 테이블의 생성·삽입·업데이트를 지원해요.

bucket(N, col) 트랜스폼은 열의 값을 N개 버킷으로 해시하는데, 고카디널리티 열에 안정적인 파티셔닝을 원할 때 유용해요. truncate(W, col)은 행을 첫 W개 문자(숫자 열의 경우 열 값을 W의 배수로 내림)로 그룹화하는데, prefix 기반 파티셔닝에 유용해요.

CREATE TABLE iceberg_catalog.default.events (
    event_id BIGINT,
    user_id BIGINT,
    country VARCHAR,
    payload VARCHAR
)
PARTITIONED BY (bucket(16, user_id), truncate(2, country));

bucket·truncate 파티셔닝 테이블에 대한 업데이트와 삭제도 지원되며, merge-on-read 시맨틱 하에 positional deletes를 사용해요.

Iceberg V3 지원

DuckDB-Iceberg는 읽기·쓰기 양쪽에서 다음 Iceberg v3 명세 기능을 지원해요:

  • VARIANTTIMESTAMP_NS 데이터 타입
  • 열의 스키마 수준 기본값
  • 바이너리 삭제 벡터 (binary deletion vectors)
  • 행 계보 추적 (row lineage tracking)

실제로 가장 큰 변화는 바이너리 삭제 벡터예요. v2 테이블에서 DuckDB-Iceberg는 positional deletes를 Parquet 파일로 써요. v3 테이블에서는 같은 정보를 훨씬 더 컴팩트한 바이너리 삭제 벡터(Puffin 파일)로 인코딩해요. DuckDB는 테이블의 format-version에 따라 올바른 형식을 자동으로 선택해요. 생성 시 format-version 테이블 속성을 설정해 v3 테이블을 만들 수 있어요:

CREATE TABLE iceberg_catalog.default.v3_table
WITH ('format-version' = 3) AS
    FROM (VALUES
        (1, {'kind': 'click', 'x': 10}::VARIANT, TIMESTAMP_NS '2026-05-20 12:00:00.123456789'),
        (2, {'kind': 'view'}::VARIANT, TIMESTAMP_NS '2026-05-20 12:00:00.987654321')
    ) t(id, payload, event_time);

경고 GEOGRAPHYUNKNOWN 타입은 아직 DuckDB-Iceberg에서 지원되지 않아요; DuckDB v2.0.0에 계획돼 있어요.

UPDATEDELETE의 제한 사항

UPDATEDELETE 연산에는 다음과 같은 제한 사항이 있어요:

  • 정렬된(sorted) 테이블에서만 동작해요. 정렬된 테이블에서 이 연산을 시도하면 [실패]해요.
  • DuckDB-Iceberg는 positional deletes만 써요(v3 테이블의 경우 바이너리 삭제 벡터로 인코딩). Copy-on-write 기능은 아직 지원되지 않아요.
  • DuckDB-Iceberg는 merge-on-read 시맨틱만 지원해요. 테이블에 write.update.modewrite.delete.mode 속성이 merge-on-read가 아닌 다른 값으로 설정되어 있으면 연산이 실패해요.

미지원 연산 (Unsupported Operations)

DuckDB iceberg 익스텐션이 아직 지원하지 않는 것은:

  • GEOGRAPHYUNKNOWN 데이터 타입 (DuckDB v2.0.0 예정)
  • UPDATE, DELETE, MERGE INTO에 대한 copy-on-write 시맨틱

더 알아보기 (Learn more)