DuckDB 2.0에서도 앱 안에 분석 엔진을 넣는 방식은 유지된다. Quack을 쓰면 여러 클라이언트의 쿼리를 별도 DuckDB 프로세스로 모을 수 있고, 비동기 I/O는 원격 파일을 읽는 동안의 대기를 줄일 여지를 만든다. 두 변화는 서로 다른 문제를 해결한다. 팀 도구로 옮길 때는 쿼리를 실행할 위치와 파일을 소유할 프로세스를 먼저 정하고, 엔진 버전뿐 아니라 새로 생성하는 DB 파일의 형식까지 이전 계획에 넣어야 한다.
혼자 쓰던 분석 스크립트를 팀 도구로 만들 때
고객지원 담당자가 매일 티켓 파일을 내려받아 처리 지연을 집계한다. Python 앱 안의 DuckDB로 잘 돌아가던 작업을 팀용 웹 화면으로 바꾸자 요구가 늘어난다. 네 개의 웹 워커가 동시에 조회하고, 배치는 새 티켓을 넣으며, 관리자는 분류 오류를 고치려 한다. 이제 문제는 SQL 한 줄의 속도뿐 아니라 어느 프로세스가 데이터와 실행 상태를 책임지는가다.
DuckDB 팀은 2026년 10월 21일 2.0.0 LTS를 공개했다. 5월의 1.5.3에서 선보인 Quack 원격 프로토콜을 개선하고 CONNECT를 추가했으며, 비동기 I/O 등 분석 엔진 기능을 확장했다. 2.0 지원은 적어도 2027년 10월까지, 1.5 지원은 이전 시간을 확보하도록 2027년 3월까지 연장했다고 안내한다. 서버가 필요한 팀에 선택지가 늘었지만, 앱 안에서 실행하는 방식을 버려야 한다는 뜻은 아니다. 공식 발표
이 글은 가상의 티켓 분석 앱으로 배치 선택을 설명한다. 제품 동작 설명은 10월 25일 확인한 공식 2.0 문서에 근거한다. 직접 실행한 부분은 뒤의 작은 로컬 DB 호환성 대조이며, Quack 서버나 S3의 속도를 측정한 사용기는 아니다.
파일을 가져오는 것과 쿼리를 보내는 것
DuckDB를 이용한 분석이라도 데이터가 오가는 경로는 다를 수 있다.
| 경로 | 쿼리를 실행하는 곳 | 네트워크로 오가는 주요 대상 |
|---|---|---|
| 앱 내부 DuckDB + 로컬 파일 | 앱 프로세스 | 로컬 분석 자체에는 네트워크가 필요 없음 |
| 앱 내부 DuckDB + 원격 Parquet | 앱 프로세스 | 원격 저장소에서 읽는 파일 데이터 |
| 클라이언트 → Quack 서버 | 서버 프로세스 | 쿼리 요청과 결과. 큰 결과는 나누어 가져옴 |
원격 파일을 SQL로 읽는다고 그 저장소가 SQL 집계를 실행하는 것은 아니다. 반대로 Quack에서는 서버 쪽에 쿼리를 보내고 결과를 받는다. 예를 들어 서버에 있는 티켓 원본에서 상품군별 건수만 구한다면, 클라이언트는 원본 행 전체를 받지 않고 집계 결과를 받을 수 있다. 이는 서버에서 그 집계를 수행하도록 구성했을 때의 차이다.
Quack 안내는 원격을 ATTACH한 뒤 CONNECT로 세션 전체를 원격에 연결하는 방식을 권장한다. 이후 쿼리는 서버에서 실행되고 결과가 돌아오며, DISCONNECT하면 로컬로 돌아온다. 단순히 ATTACH해서 원격 테이블과 로컬 자료를 조합하는 사용도 가능하므로, “연결했다”는 말만으로 모든 연산의 실행 위치를 판단하면 안 된다.
HTTP 기반이라고 결과 크기가 사라지는 것도 아니다. SELECT *로 티켓 본문까지 전부 내려받으면 여전히 많은 결과를 전송한다. 큰 결과에는 후속 FETCH 요청이 필요하다는 문서 설명도 있다. 원격 집계의 이점을 얻으려면 서버에서 줄일 행과 열, 클라이언트에서 실제 보여 줄 결과를 먼저 정해야 한다.
웹 워커 네 개가 같은 파일을 열면 되는가
공유 디스크의 support.duckdb를 네 워커가 각각 쓰기 모드로 열도록 바꾸는 것은 Quack 도입과 다르다. DuckDB의 네이티브 DB 파일에 대한 읽기·쓰기는 한 프로세스 안에서 여러 스레드가 수행하는 구조다. 공식 동시성 문서는 여러 프로세스의 쓰기를 Quack을 통한 클라이언트·서버 경로로 설명한다. 또한 같은 행을 동시에 수정하는 트랜잭션은 충돌할 수 있다고 명시한다. 동시성 모델
다음은 이 계약을 토대로 설계한 가상 구성이다. Quack에 연결한 배치도 서버로 갱신을 보내고, 웹 워커는 서버에 집계를 요청한다. 파일을 여는 주체는 서버 프로세스다. 워커 수가 늘어난다고 DB 파일을 직접 쓰는 프로세스 수를 늘리지 않는다.
자체 제작한 배치 설명도다. 실제 서버 실행 화면이나 처리량 측정 결과가 아니다. 아래 원격 파일 읽기 경로는 필요할 때 추가하는 구성이다.
이 배치에서 얻는 것은 실행·갱신 경로를 한곳에 모으는 단순함이다. 동시에 서버가 멈추면 연결된 분석 요청이 함께 영향을 받는다. 웹 워커 네 개를 띄웠다는 사실만으로 DB의 고가용성이나 네 배 처리량을 얻지는 않는다. 이 글은 복제·자동 장애 전환 구성을 검증하지 않았다.
업무 요구에 따라 서버 자체를 생략할 수도 있다. 매일 아침 한 번 확정된 집계만 보여 주면 된다면, 배치가 만든 읽기 전용 산출물을 배포하는 편이 간단하다. 반면 사용자가 최신 티켓 분류를 고친 뒤 다시 집계해야 한다면 공유 쿼리 경로의 가치가 커진다. 초당 많은 소규모 주문 갱신이 핵심이라면 분석 편의만으로 기존 운영 DB를 교체할 이유는 약하다.
같은 서버를 본다고 같은 시점의 보고서가 되는 것은 아니다
가상 앱에서 배치가 원본 티켓과 분류 매핑을 따로 갱신한다고 하자. 중간에 들어온 보고서는 새 티켓과 옛 매핑을 조합할 수 있다. 따라서 이전 설계에는 연결 방식과 함께 어떤 갱신을 한 트랜잭션으로 묶고 언제 읽을 수 있게 할지가 필요하다. Quack 연결만으로 업무상 완결된 갱신 단위가 정해지지는 않는다.
필자의 제안은 배치에 batch_id를 부여하고, 보고서에도 그 식별자를 표시하는 것이다. “두 사람이 같은 화면에서 다른 수치를 보았다”는 제보를 받으면 먼저 같은 배치를 읽었는지 대조할 수 있다. 보고서가 여러 쿼리로 만들어진다면 쿼리 사이의 갱신도 고려해야 한다. 구체적인 트랜잭션 경합은 자신의 앱으로 시험해야 하며, 격리 수준과 업무 불변식의 구분이 설계 질문을 정하는 데 도움이 된다. 해당 글의 PostgreSQL 동작을 DuckDB에 그대로 적용한다는 뜻은 아니다.
비동기 I/O는 읽기 대기를 어떻게 바꾸나
원격 Parquet를 읽는 워커가 요청을 보낸 뒤 도착할 때까지 멈춰 있으면, CPU와 네트워크에 여유가 있어도 진행이 느릴 수 있다. DuckDB 2.0은 읽기를 미리 예약하고 별도의 I/O 스레드 풀로 요청을 처리한다. 쿼리 워커는 이미 도착한 데이터를 해독·집계하고, 다음 자료는 그동안 들어온다. 핵심은 기다리는 일과 계산하는 일을 겹치는 것이다. I/O 설계와 설정
현재 문서의 자동 비동기 읽기 지원 범위는 Parquet, 압축하지 않은 탐색 가능한 UTF-8 CSV, DuckDB 네이티브 저장 형식이다. JSON 등 다른 형식은 동기 I/O를 사용한다. 따라서 “2.0으로 올리면 모든 파일 읽기가 비동기가 된다”는 결론은 맞지 않는다.
앞의 티켓 앱이 이미 로컬의 작은 집계표만 읽는다면 이 변화의 이득은 작을 수 있다. 원격 Parquet를 많이 읽는데 네트워크를 충분히 쓰지 못했다면 비교할 이유가 생긴다. 그래도 다음 두 조건은 확인해야 한다.
- Parquet의 row group처럼 나누어 읽을 작업이 충분해야 한다. 작업 단위가 적으면 I/O 스레드만 늘려도 병렬 읽기를 채울 수 없다.
- 미리 받은 데이터도 메모리를 쓴다. 문서의 기본 read-ahead는 메모리 예산의 영향을 받으며, 압박이 커지면 미리 읽는 큐가 줄어든다. 병렬성을 늘리는 설정을 작은 서버에 그대로 복사하지 않는다.
도입 전후 비교는 같은 파일·질의·결과·캐시 조건에서 해야 한다. 총 지연과 읽은 바이트, CPU·메모리 사용을 함께 보면 파일 대기인지 집계 계산인지 구분하기 쉽다. 네트워크가 이미 포화된 경우나 클라이언트에 대량 결과를 보내는 것이 병목인 경우에는 다른 대책이 필요하다. 이 글은 특정 속도 향상률을 보장하지 않는다. 여러 단계의 시간은 지연을 나누어 관측하는 방법으로 이어서 볼 수 있다.
팀에 열기 전에 접근 범위를 정한다
Quack 서버는 서버 세션이 볼 수 있는 테이블에 대한 읽기·쓰기 SQL 표면을 노출한다. 기본 구성은 토큰 인증과 localhost 바인딩을 사용하지만, 기본 인가 콜백은 쿼리를 그대로 통과시킨다. 팀원이 연결할 수 있다는 것과 팀원별로 허용할 작업을 나눈다는 것은 별도 설정이다. 외부 연결에서는 localhost 서버 앞에 TLS를 종료하는 역방향 프록시를 두는 방식을 공식 문서가 권장한다. Quack 보안 계약
가상 티켓 앱이라면 운영자가 쓰는 갱신 경로와 조회자의 경로를 구분하고, 서버에 붙여 둔 다른 자료까지 의도치 않게 노출하지 않는지 확인해야 한다. SQL 앞부분이 SELECT나 WITH인지 검사하는 간단한 정규식은 신뢰할 읽기 전용 정책이 아니다. 공식 문서도 WITH로 시작하는 쓰기 문장을 반례로 든다. 읽기 전용 DB 연결이나 파싱된 문장 유형을 검사하는 인가처럼 실제 정책을 구현해야 한다.
이 문단의 목적은 모든 분석 앱에 복잡한 보안 체계를 요구하는 것이 아니다. 혼자 쓰던 프로세스를 여러 사람의 실행 지점으로 바꾸면, 같은 데이터에 누가 어떤 SQL을 실행하는지가 배치 선택의 일부가 된다.
직접 대조: 엔진을 되돌려도 파일이 열리지 않을 수 있다
공식 이전 문서에서 가장 먼저 경고하는 변경은 기본 저장 형식이다. 2.0에서 새로 만든 기본 DB 파일은 2.0 이전 버전이 읽지 못한다. 반면 이전 버전에서 만든 파일을 2.0으로 열어 쓰는 경우에는 기존 저장 버전을 유지한다. 새 파일을 호환 가능한 형식으로 명시해 만드는 경로도 있다. 이전 안내, 저장 형식 계약
2026년 10월 25일 macOS 26.5.2 arm64에서 공식 CLI 1.5.6과 2.0.0을 내려받아, 직접 만든 정수 테이블로 아래를 실행했다. 빌드 식별자는 각각 069cc9f9b5, d54cbbe3df다. 임시 디렉터리에서 순차 실행했고 개인 초기화 파일 대신 /dev/null을 지정했다.
| 실행한 대조 | 실제 관측 | 이전 계획에 주는 의미 |
|---|---|---|
| 2.0 기본 설정으로 새 파일 생성 → 1.5.6으로 열기 | 종료 코드 1. 저장 버전 69를 읽지 못한다는 오류 | 새 파일이 생긴 뒤에는 실행 파일만 교체하는 롤백이 실패할 수 있음 |
| 1.5.6으로 생성·1행 삽입 → 2.0으로 1행 추가 → 1.5.6 조회 | 정상 종료, 행 수 2 | 기존 파일을 여는 것과 새 형식으로 만드는 것은 다름 |
2.0에서 STORAGE_VERSION 'v1.5.6'으로 생성 → 1.5.6 조회 |
정상 종료, 넣었던 정수 7 반환 | 필요한 구버전을 먼저 정하고 호환 형식 생성을 시험할 수 있음 |
| 같은 정규식 식을 두 버전에서 실행 | 아래와 같이 결과가 달라짐 | 파일 호환만으로 보고서 의미까지 같다고 볼 수 없음 |
마지막 대조에 사용한 쿼리는 다음과 같다.
SELECT 'abc' ~ 'b' AS matched;
1.5.6은 false, 2.0.0은 true를 반환했다. 2.0에서는 이 연산자가 부분 정규식 일치로 바뀌었다는 공식 이전 문서와 일치했다. 티켓 분류 규칙이 정규식의 전체 일치를 기대했다면, 쿼리가 오류 없이 끝나도 집계에 들어오는 행이 달라질 수 있다.
이는 작은 정수 테이블과 한 표현식의 실제 대조다. 모든 타입·확장·Python 코드의 호환성, 동시 쓰기나 서버 복구를 검증한 결과로 확대할 수 없다. 호환 형식으로 새 파일을 만드는 선택 역시 2.0의 모든 기능을 구버전에 가져다준다는 뜻은 아니다.
직접 실행한 호환성 대조 예제 ZIP에는 자체 작성한 Python 검사와 설명서가 들어 있다. DuckDB 바이너리는 포함하지 않는다. 두 버전의 공식 CLI를 각각 준비한 뒤 압축을 푼 폴더에서 실행한다.
python3 check-storage.py /path/to/2.0.0/duckdb /path/to/1.5.6/duckdb
Python 3와 macOS 또는 Linux 형태의 CLI 경로를 전제로 하며, 이 글에서 직접 확인한 환경은 위 macOS arm64다. 스크립트는 임시 파일을 만들고 종료 시 제거한다. 운영 DB를 인자로 받지 않는다. 결과 JSON의 passed뿐 아니라 각 문장의 버전·종료 코드·출력을 함께 읽으면 어느 조건에서 달라졌는지 알 수 있다.
도입 결정을 한 장으로 남기기
이번 릴리스에서 먼저 바꿀 것을 고르려면 팀의 질문을 다음처럼 나눌 수 있다. 아래는 제품 성능표가 아니라 앞의 가상 앱에 적용한 편집 판단이다.
| 현재 불편 | 우선 검토할 변경 | 그대로 남는 일 |
|---|---|---|
| 앱마다 같은 원본을 받아 중복 집계 | 서버에서 집계하고 필요한 결과만 전달 | 결과 크기·서버 자원·운영 담당 결정 |
| 여러 프로세스가 갱신을 공유해야 함 | Quack으로 파일 소유 프로세스에 요청 집중 | 갱신 트랜잭션·충돌 처리·접근 정책 |
| 원격 파일 대기 동안 자원이 남음 | 지원 형식에서 2.0 비동기 I/O 비교 | 파일 배치·메모리·네트워크 관측 |
| 매일 확정된 숫자만 배포하면 됨 | 기존 배치와 읽기 전용 산출물 유지도 검토 | 갱신 시각·배치 식별자 표시 |
실제 전환 전에는 다음 기록을 채워 두면 좋다.
보고서: 예) 전일 고객지원 티켓의 상품군별 처리 지연
쿼리 실행 위치 / DB 파일 소유 프로세스:
새로 파일을 만드는 경로: 배치, 재시작 초기화, 임시 분석, 내보내기
남아 있는 구버전 독자: CLI, 웹 워커, 예약 배치
갱신 단위와 보고서 batch_id:
대조할 결과: 행 수, 핵심 합계, 분류별 건수, NULL·정규식 반례
전환 전 보관할 것: DB 복구본, 실행 파일, 확장과 설정의 버전
되돌림 조건과 방법: 파일 복원 범위, 전환 뒤 갱신분의 보존·재적용
아직 시험하지 않은 것: 원격 연결, 동시 갱신, 장애 후 복구
특히 전환 뒤 새로 들어온 데이터를 어떻게 보존할지 결정하지 않은 백업 복원은 완전한 롤백 계획이 아니다. 먼저 운영과 분리된 복제 환경에서 파일 생성 경로와 주요 질의를 대조하고, 원격 공유는 그다음 단계로 시험할 수 있다. 공식 이전 안내도 shadow system을 권장하며 중요 업무에는 후속 패치를 기다리는 선택을 제시한다.
보고서 정의 자체가 아직 불명확하다면 분석 질문과 데이터 범위를 맞추는 사례를 먼저 읽어도 좋다. 실행 위치를 바꾸어도 잘못 정의한 분모나 기간은 그대로다. 이 글의 표와 기록 양식은 전환 검토 때 다시 볼 수 있도록 저장하고, 후속 글은 사이트의 RSS로 받아볼 수 있다.
- Quack은 쿼리를 서버에 보내는 경로다. 원격 Parquet 읽기나 여러 프로세스의 동일 DB 파일 직접 쓰기와 구분해야 한다.
- 비동기 I/O는 읽기 대기와 쿼리 처리를 겹친다. 지원 형식·병렬 작업 수·메모리·네트워크 조건에 따라 이득이 달라진다.
- 직접 대조한 2.0 기본 신규 파일은 1.5.6에서 열리지 않았다. 기존 형식 유지와 명시적 호환 형식 생성은 별도 선택이며, 파일이 열려도 SQL 결과가 달라질 수 있다.
근거와 원자료
자료의 발행 시점과 이번 글에서 참고한 범위를 함께 기록합니다.
- Announcing DuckDB 2.0.0 LTS “Cinnamon Teal” ↗DuckDB Foundation / DuckDB team · 2026
10-21 정식 공개; Quack 최초 등장은1.5.3,2.0 개선; LTS기간. 공급자 속도 수치 미채택.
- Quack Remote Protocol ↗DuckDB Foundation / DuckDB team · 2026
2.0 live문서 확인. HTTP, ATTACH/CONNECT/DISCONNECT, 결과 FETCH, 서버 실행 위치. 실제 서버 실행 아님.
- Concurrency ↗DuckDB Foundation / DuckDB team · 2026
네이티브 파일의 단일 writer process, 프로세스 내 낙관적 동시성, Quack 다중 클라이언트 경로.
- I/O — Asynchronous I/O ↗DuckDB Foundation / DuckDB team · 2026
지원 형식, I/O/worker pool, read-ahead 메모리와 row group 제약. 성능 배수 채택 안 함.
- Quack Security ↗DuckDB Foundation / DuckDB team · 2026
localhost/token 기본값, 기본 인가 permissive, reverse proxy 권고, prefix regex 반례.
- Migrating to DuckDB 2.0 ↗DuckDB Foundation / DuckDB team · 2026
새 기본 파일69·이전 파일 유지·정규식 의미 변경·shadow system 권고. 별도 로컬 CLI대조와 구분.
- Storage Versions and Format ↗DuckDB Foundation / DuckDB team · 2026
형식 호환 방향,STORAGE_VERSION의 최소 독자 버전, 신규/기존 파일 차이.
갱신 기록
DuckDB 2.0 공식 발표·문서 분석과 가상 팀 분석 앱 배치 비교. macOS arm64 CLI 1.5.6·2.0.0으로 파일 호환성 세 경우와 정규식 의미를 대조했다. Quack 서버·S3·다중 클라이언트 성능은 실행하지 않았다.
오류를 발견했다면 댓글로 알려 주세요 →
이 글에 댓글 남기기
댓글 공개 방식을 확인하고 있습니다. 개인정보나 비밀 값은 적지 마세요.
댓글을 불러오는 중입니다.
내 댓글 확인·수정·삭제
등록 후 안내된 댓글 번호와 비밀번호를 입력하세요. 승인 대기 중인 댓글도 확인할 수 있습니다.