버전·설치·런타임 기준
DuckDB 2.0 LTS, 1.5 전환 경로, 저장 포맷·SQL·Python 호환성을 함께 고정하는 운영 기준
핵심 요약
- 2026-10-26 기준 최신 안정판은 2.0.0 LTS입니다. 1.5.6은 전환 검증 기간의 대안이며 1.4.5 LTS는 지원 종료가 가깝습니다.
- 버전 업그레이드는 엔진·클라이언트·확장·저장 포맷을 한 묶음으로 검증합니다.
- 2.0 신규 파일을 구버전 reader가 읽어야 한다면 생성 시 storage compatibility를 지정합니다.
- Python 2.0 client는 Python 3.11 이상이 필요합니다. 분석 통합 패키지의 2.0 지원 여부도 별도로 확인합니다.
지원 기간과 선택
| 릴리스 | 2026-10-26 상태 | 운영 선택 |
|---|---|---|
| 2.0.0 LTS | 10월 21일 출시, 최소 2027년 10월까지 지원 | 신규 기능과 호환성 검증의 기준 |
| 1.5.6 | 지원을 2027년 3월까지 연장 | 중요 배치는 2.0 shadow 검증 또는 후속 patch 대기 가능 |
| 1.4.5 LTS | 2026-11-17 지원 종료 | 1.5 또는 2.0으로 이전할 일정을 확정 |
| 2.0.1 | 11월 18일 예정 | 출시된 버전으로 취급하지 않음; 일정은 변경 가능 |
Release Calendar의 예정일과 실제 출시일을 구분합니다. 모든 운영 작업을 즉시 major upgrade할 필요는 없으며, 공식 migration도 중요 워크로드에 shadow system 검증을 권장합니다.
설치와 버전 고정
# Python 3.11+의 별도 가상환경에서 실행
python -m pip install 'duckdb==2.0.0'
python -c 'import duckdb; print(duckdb.__version__)'CLI는 공식 설치 페이지에서 플랫폼별 2.0.0 배포를 선택하고 duckdb --version으로 확인합니다. Python·R·JDBC·ODBC·확장은 배포 시점이 다를 수 있습니다. Node.js의 기존 duckdb 패키지와 @duckdb/node-api도 다른 클라이언트이므로 npm의 latest만 비교하지 않습니다.
이 책의 SQL 실습은 2.0.0 기준입니다. dbt·Ibis·MotherDuck 등의 호환성은 각 프로젝트의 lockfile과 지원표로 별도 판정합니다.
저장 포맷: 새 파일과 기존 파일
2.0 신규 파일의 기본 storage version은 69이며 이전 엔진이 읽을 수 없습니다. 반대로 2.0은 기존 파일을 읽고 쓸 수 있고 그 파일의 저장 버전을 유지합니다. 기존 파일을 새 형식으로 전환하려면 export/import 또는 명시적인 복사를 계획합니다.
import duckdb
# 새 출력 파일을 1.5 reader와 공유하는 경우
con = duckdb.connect(
'compatible-output.duckdb',
config={'storage_compatibility_version': 'v1.5.6'},
)
try:
con.execute('CREATE TABLE IF NOT EXISTS result (id BIGINT)')
print(con.execute('SELECT database_name, tags FROM duckdb_databases()').fetchall())
finally:
con.close()파일을 공유하는 writer·reader·BI client를 모두 inventory에 넣습니다. 호환 포맷으로 저장할 수 없는 새 기능은 별도 결과물로 분리하고, rollback은 구버전 실행 파일뿐 아니라 구버전이 읽을 수 있는 데이터까지 준비합니다.
SQL 회귀 점검
| 변경 | 필요한 수정 |
|---|---|
x -> x + 1 lambda 기본 비활성화 | lambda x: x + 1; 임시 호환 flag는 2.1에서 제거 예정 |
~·!~가 부분 정규식 매칭 | 완전 일치가 필요하면 regexp_full_match() 또는 명시적 앵커 |
2 * 3! 우선순위 변경 | 2.0 결과는 12; 이전 의미는 (2 * 3)!로 명시 |
X'AB'·B'101' 리터럴 | 문자열 대신 BLOB·BIT 타입; 입력/출력 스키마 회귀 확인 |
정수 //·%의 0 나누기 오류 | 의도적으로 NULL을 원할 때 TRY(...); 일반 /는 별도 동작 |
같은 target을 여러 source row가 갱신하는 MERGE 오류 | source를 결정적으로 중복 제거하거나 unique match 보장 |
| 타입 없는 NULL 컬럼은 NULL 타입 유지 | NULL::VARCHAR처럼 의도한 타입 명시 |
preserve_identifier_case 값 형태 변경 | preserve_case·lowercase·uppercase 사용 |
| S3 URL의 설정 query parameter 기본 비활성화 | credential과 scope는 Secrets Manager로 전달 |
| 일부 profiling·HTTP logging 설정 제거 | tracked_metrics, CALL enable_logging('HTTP') 등 현행 API 확인 |
일부 변경은 컴파일 실패 없이 결과만 달라집니다. row count뿐 아니라 NULL 분포·정규식 결과·금액 합계·중복 key를 비교하세요. 실습에 전환 확인용 SQL을 추가했습니다.
실행 기록
SELECT version();
SELECT name, value
FROM duckdb_settings()
WHERE name IN ('memory_limit', 'threads', 'temp_directory',
'storage_compatibility_version', 'preserve_identifier_case');
SELECT extension_name, extension_version, installed_from
FROM duckdb_extensions()
WHERE installed;엔진, client, extension, session setting, 입력 manifest, 출력 storage version을 같은 실행 기록으로 남깁니다. 확장 바이너리는 엔진·플랫폼·ABI 호환성을 확인해 재설치하고, 단순히 이전 확장 디렉터리를 복사하지 않습니다.
자체 빌드와 플랫폼 이전
2.0 소스 빌드는 C++17 컴파일러가 필요합니다. C API v2는 아직 안정화 전이므로 자체 확장은 엔진 버전별 빌드·실행 검증을 둡니다. ICU 외부 라이브러리 의존성 제거가 시간대 기능 제거를 뜻하지는 않습니다. icu 확장의 네이티브 구현을 사용하며, 커스텀 빌드는 시간대·collation 결과를 비교합니다.
Intel Mac의 osx_amd64는 2.0 core 지원과 community 확장 배포를 구분해야 합니다. community 확장은 더 이상 이 플랫폼용으로 빌드되지 않으며, 2.1에서는 플랫폼 지원 종료가 예정되어 있습니다. 2.0 배포·폐기 안내.
전환 승인에는 새 파일의 구버전 읽기, 기존 파일의 2.0 쓰기 후 구버전 읽기, 쿼리 결과와 타입 비교, 연동 패키지 실행을 포함합니다. 호환성 설정만 조회한 결과와 실제 구버전 reader로 재개방한 결과는 별도로 기록합니다.
MERGE와 UPDATE FROM의 중복 매칭은 다르다
MERGE가 같은 target을 여러 번 갱신하려 하면 오류가 나지만, UPDATE ... FROM은 일치하는 source 중 하나를 사용하고 그 선택은 정해져 있지 않습니다. 두 구문 모두 source key를 고유하게 만들고, 최신 revision이 같은 경우의 tie-breaker까지 정해야 재현 가능합니다. UPDATE의 다중 source 매칭.