LLM WikiAccess-protected knowledge portal
← 스터디 홈
115편 · 약 15분

DuckDB v2.0 Cyanoptera 프리뷰: 서버·트리거·비동기 I/O로 임베디드 OLAP의 경계를 다시 그은 방법

요약

2026년 8월 17일, DuckDB 팀이 v2.0 "Cyanoptera"의 핵심 기능을 사전 공개했다. 정식 릴리스는 2026년 가을 예정이다. 이번 메이저 버전은 "DuckDB를 서버로 쓰는 해"의 시작을 선언하며, Quack 프로토콜 정식 졸업·전면적 트리거 지원·비동기 I/O GA·새 기본 스토리지 포맷·리팩토링된 C API를 한꺼번에 가져온다. v1 데이터베이스 파일은 v2에서 바로 열리지 않는다. 업그레이드 전에 익스포트·재임포트 계획이 필요하다.


배경

DuckDB 1.5 Variegata(2026년 3월)는 VARIANT 타입·PEG 파서 도입으로 분석 엔진의 폭을 넓혔다. 당시 Quack 프로토콜은 실험적 익스텐션 수준이었고, 트리거는 지원하지 않았으며, I/O는 동기적이었다. 1.x 계열 전반에 걸쳐 기능이 누적되면서 두 가지 압박이 커졌다.

  1. 서버 모드 수요: DuckDB를 프로세스 경계 없이 원격에서 쿼리하려는 팀이 늘었다. PostgreSQL 프로토콜 에뮬레이션(pg wire)이나 HTTP REST 래퍼 같은 우회 방법이 생태계에 난립했다.
  2. 네트워크 스토리지의 일반화: EC2/S3 구성에서 동기 I/O는 대역폭을 다 쓰지 못하는 병목이 됐다. 병렬 비동기 읽기가 필요했다.

v2.0은 이 두 요구를 정면으로 해결하면서, 메이저 버전 번호에 걸맞는 비호환 변경을 함께 가져왔다.


DuckDB v2.0 아키텍처 변화 클라이언트 any DuckDB Quack 프로토콜 (Stable) HTTP/2 · 내부 벡터 블록 직렬화 CONNECT … ATTACH … 1 RTT DuckDB 코어 엔진 트리거 (신규) BEFORE/AFTER ROW/STATEMENT 신규 SQL 파서 PG 파서 대체 확장 가능 PEG 비동기 I/O (GA) Parquet·CSV 병렬 원격 읽기 C API 재설계 비호환 변경 언어 바인딩 영향 새 기본 스토리지 포맷 (v2) v1 .db 파일 비호환 — EXPORT DATABASE / IMPORT 필요 256KB 블록·8바이트 체크섬·새 매직 헤더 ⚠ v2.0 비호환 변경 체크리스트 스토리지 포맷: v1 .db 파일 직접 열기 불가 C API: 언어 바인딩 재컴파일 필요 ICU 익스텐션: 타임존·정렬 결과 일부 변경
그림 1. DuckDB v2.0의 핵심 변화 구조 — Quack 서버 레이어, 비동기 I/O, 트리거, 새 스토리지가 추가된 아키텍처

Quack 프로토콜 정식 졸업

무엇이 달라지나

v1.5에서 실험적으로 도입된 Quack은 v2.0에서 안정(stable) 익스텐션으로 졸업한다. 어떤 DuckDB 프로세스든 네트워크 너머의 다른 DuckDB에 붙어 쿼리할 수 있다.

-- 원격 DuckDB에 연결
CONNECT 'duckdb://hostname:5461/mydb';

-- 연결된 DB를 로컬처럼 ATTACH
ATTACH 'duckdb://hostname:5461/sales' AS remote;
SELECT * FROM remote.transactions LIMIT 10;

프로토콜 설계

Quack은 PostgreSQL wire 프로토콜을 쓰지 않는다. 대신 HTTP/2 위에서 DuckDB 내부 벡터 블록을 그대로 직렬화해 전송한다. WAL 직렬화와 같은 코드 경로를 재사용하기 때문에 인터체인지 포맷(JSON, Arrow IPC 등)으로 변환할 필요가 없다.

쿼리 1건당 필요한 왕복(RTT)은 단 한 번이다. 대용량 결과는 후속 FETCH 요청으로 청크 스트리밍하며, 다중 스레드 병렬 FETCH도 지원한다.

항목PostgreSQL wireQuack
전송 프로토콜TCPHTTP/2
직렬화텍스트 / 바이너리 혼합DuckDB 내부 벡터 블록
쿼리당 RTT여러 번1번
복잡 타입 충실도손실 가능완전 보존
표준 호환 클라이언트psql, JDBC 등DuckDB 클라이언트만

Quack을 쓰려면 양쪽 모두 DuckDB여야 한다. PostgreSQL 클라이언트로 연결해야 한다면 기존 pg_wire 우회 방법을 유지해야 한다.


트리거 지원

전면 지원 범위

v2.0은 SQL 표준 트리거를 처음으로 완전하게 지원한다.

-- AFTER INSERT 트리거: audit 테이블에 기록
CREATE TRIGGER log_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
  INSERT INTO audit_log(table_name, action, row_id, ts)
  VALUES ('orders', 'INSERT', NEW.id, now());
END;

-- BEFORE UPDATE 트리거: 불변 컬럼 보호
CREATE TRIGGER guard_immutable
BEFORE UPDATE ON products
FOR EACH ROW
WHEN (OLD.created_at IS DISTINCT FROM NEW.created_at)
BEGIN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'created_at is immutable';
END;

지원 범위:

  • 타이밍: BEFORE / AFTER
  • 이벤트: INSERT / UPDATE / DELETE
  • 단위: FOR EACH ROW / FOR EACH STATEMENT
  • 전환 테이블: REFERENCING OLD TABLE AS ... NEW TABLE AS ...
  • 기타: 이벤트당 복수 트리거, RETURNING 지원, DROP TRIGGER

DuckDB는 분석 쿼리 중심 엔진이라 OLTP처럼 트리거를 남발하는 패턴보다는 CDC-lite(변경 추적)나 데이터 품질 보호 용도에 가장 잘 맞는다.


비동기 I/O GA

왜 중요한가

동기 I/O 모델에서는 스레드가 디스크·네트워크 응답을 기다리는 동안 CPU가 놀았다. S3 같은 원격 오브젝트 스토리지에서 Parquet를 읽으면 I/O 지연이 수십~수백 밀리초에 달하고, 동기 모델은 이 지연을 직렬로 쌓는다.

v2.0의 비동기 I/O는 I/O 레이어와 쿼리 처리 레이어를 분리한다.

  • I/O 요청은 비동기로 발행되고, 완료 알림을 받으면 처리 레이어가 해당 데이터를 소비한다.
  • 원격 읽기에서 수십 개의 병렬 요청을 동시에 날릴 수 있어, 대역폭 포화(bandwidth saturation) 지점까지 I/O 처리량이 늘어난다.
  • CSV와 Parquet 모두 적용된다.

EC2 + S3 구성처럼 컴퓨트와 스토리지가 분리된 환경에서 특히 효과가 크다. 동기 모델에서는 대역폭이 남아도 요청이 직렬이라 다 쓰지 못했던 구조적 낭비가 해소된다.


새 SQL 파서와 스토리지 포맷

SQL 파서 교체

DuckDB는 PostgreSQL 유래 파서를 오래 사용해 왔다. v2.0은 자체 개발한 PEG 기반 파서로 교체한다. PEG 파서는 새 SQL 구문 확장이 쉽고, 에러 메시지를 더 세밀하게 제어할 수 있다. v2에서 추가된 구문들(OVERLAY, UNNEST in GROUP BY, FETCH FIRST n ROWS WITH TIES 등)은 이 새 파서의 혜택을 받는다.

새 기본 스토리지 포맷 — 마이그레이션 필수

v2.0의 가장 큰 운영 리스크다. DuckDB v2.0이 쓰는 스토리지 버전은 v1.x와 호환되지 않는다. v1에서 만든 .db 파일을 v2에서 그냥 열면 오류가 발생한다.

권장 마이그레이션 경로:

-- v1.x 환경에서 실행
EXPORT DATABASE '/tmp/mydb_export' (FORMAT PARQUET);

-- v2.0 환경에서 실행
IMPORT DATABASE '/tmp/mydb_export';

정식 릴리스 전에 팀이 운영 중인 DuckDB 파일 목록을 파악하고 마이그레이션 계획을 세워 두어야 한다.

ICU 익스텐션과 타임존 변경

v2.0은 ICU 라이브러리(국제화 표준 라이브러리)를 완전히 제거하고, icu 익스텐션이 직접 IANA 타임존 데이터베이스를 내장해 구현한다. 약 45 kB로 압축된 타임존 데이터를 번들링하며, 외부 ICU 의존성이 사라진다. 기존 코드에서 일부 타임존·정렬 동작이 미묘하게 달라질 수 있으므로 테스트가 필요하다.


C API 재설계

DuckDB의 C API는 Python·R·Java·Go 등 언어 바인딩의 기반이다. v2.0은 C API를 메이저 버전에 맞게 재설계했다. 기존 바인딩 라이브러리들은 재컴파일 또는 업데이트가 필요하다. duckdb-python, duckdb-r 등 공식 패키지는 v2.0에 맞춰 함께 업데이트될 예정이지만, 서드파티 바인딩은 각자 대응 일정을 확인해야 한다.


SQL 표준 준수 강화

v2.0은 여러 SQL 표준 구문을 추가·수정했다.

기능설명
FETCH FIRST n ROWS ONLYSQL 표준 행 제한 (LIMIT의 표준 표현)
OVERLAY(str PLACING repl FROM pos FOR len)문자열 치환 함수
UNNEST in GROUP BY배열을 GROUP BY 키로 바로 전개
MERGE / UPDATE ... FROM다중 매칭 행에 대한 명확한 의미론

운영자 점검 체크리스트

v2.0이 가을에 정식 출시되기 전, 지금부터 준비할 사항:

  1. 파일 인벤토리: 운영 중인 .db 파일 목록 작성. 파일이 v1.x로 생성됐다면 마이그레이션 대상.
  2. 바인딩 버전 확인: Python, R, Java, Go 바인딩이 v2.0 C API와 호환되는지 릴리스 전에 확인.
  3. Quack 활성화 여부 결정: 서버 모드가 필요한 팀은 Quack을 활성화할지, pg_wire 우회를 유지할지 결정.
  4. 타임존·정렬 회귀 테스트: ICU 교체로 인한 결과 차이를 비교하는 회귀 테스트 작성.
  5. 비동기 I/O 프로파일링: EC2/S3 환경이라면 v2.0 베타에서 I/O 처리량 비교 측정.

Open question: 정식 릴리스에서 v1 → v2 자동 마이그레이션 도구가 제공될지, 현재 공개된 프리뷰에서 확정되지 않았다. 출시 전 공식 마이그레이션 가이드를 확인해야 한다.


References

  • DuckDB v2.0 highlights blog post (2026-08-17): https://duckdb.org/2026/08/17/duckdb-20-highlights
  • DuckDB Async I/O post (2026-07-31): https://duckdb.org/2026/07/31/asynchronous-io
  • DuckDB Quack protocol overview: https://duckdb.org/docs/current/quack/overview
  • Quack FAQ: https://duckdb.org/quack/faq
  • InfoQ: DuckDB Quack protocol news (2026-05): https://www.infoq.com/news/2026/05/duckdb-quack-protocol/
  • DuckDB 1.5 Variegata announcement: https://duckdb.org/2026/03/09/announcing-duckdb-150
  • DuckDB storage versions documentation: https://duckdb.org/docs/current/internals/storage
  • MotherDuck DuckDB ecosystem newsletter April 2026: https://motherduck.com/blog/duckdb-ecosystem-newsletter-april-2026/