익스텐션 버전 관리
익스텐션 버전 관리 (Versioning of Extensions)
익스텐션 버전 관리 (Extension Versioning)
대부분의 소프트웨어는 어떤 버전 번호를 갖고 있어요. 버전 번호는 몇 가지 중요한 목적을 담당해요:
- 바이너리를 소스 코드의 특정 상태에 묶기
- 예상 기능 세트를 파악할 수 있게 하기
- API의 상태를 파악할 수 있게 하기
- 버그 리포트를 효율적으로 처리하게 하기(예: 버그
#1337이 버전v3.4.5에서 도입됨) - 릴리스의 시간적 순서를 파악하게 하기(예: 버전
v1.2.3은v1.2.4보다 오래됨) - 예상 안정성을 알려 주기(예:
v0.0.1은 아마 별로 안정적이지 않지만v13.11.0은 안정적일 것)
DuckDB 자체처럼 DuckDB 익스텐션도 고유한 버전 번호를 가져요. 다양한 익스텐션에서 이 버전 번호의 일관된 시맨틱을 보장하기 위해 DuckDB의 Core Extensions는 익스텐션을 어떻게 버전 관리해야 하는지 규정하는 버전 관리 스킴을 사용해요. Core Extensions용 버전 관리 스킴은 unstable, pre-release, stable이라는 3가지 안정성 수준으로 구성돼요. 각 수준을 살펴보고 그 형식을 설명할게요.
출처: 문서
본문
불안정 익스텐션 (Unstable Extensions)
Unstable 익스텐션은 현재 안정성이나 안정화 목표에 대해 어떤 보장도 할 수 없는(또는 하길 원하지 않는) 익스텐션이에요. Unstable 익스텐션은 익스텐션의 짧은 git 해시로 태그돼요.
예를 들어 이 글을 쓰는 시점에 vss 익스텐션의 버전은 690bfc5 버전의 unstable 익스텐션이에요.
unstable 형식의 버전 번호를 가진 익스텐션에서 기대할 수 있는 건 뭘까요?
- 익스텐션의 소스 코드 상태는 익스텐션 저장소에서 해시를 조회해 찾을 수 있어요
- 기능이 매 릴리스마다 바뀌거나 완전히 제거될 수 있어요
- 이 익스텐션의 API가 매 릴리스마다 바뀔 수 있어요
- 이 익스텐션은 구조화된 릴리스 주기를 따르지 않을 수 있고, 새(파괴적인) 버전이 언제든 푸시될 수 있어요
사전 릴리스 익스텐션 (Pre-Release Extensions)
Pre-release 익스텐션은 Unstable 익스텐션에서 한 단계 더 나아간 것이에요. SemVer 형식, 더 정확히는 v0.y.z 형식의 버전으로 태그돼요. 시맨틱 버전 관리에서 v0으로 시작하는 버전은 특별한 의미를 가져요: 일반(>v1.0.0) 버전의 더 엄격한 시맨틱이 아직 적용되지 않음을 나타내요. 기본적으로 익스텐션이 stable 익스텐션이 되기 위해 진행 중이지만 아직 완전히 그렇진 않다는 뜻이에요.
예를 들어 이 글을 쓰는 시점에 delta 익스텐션의 버전은 v0.1.0 버전의 pre-release 익스텐션이에요.
pre-release 형식의 버전 번호를 가진 익스텐션에서 기대할 수 있는 건?
- 익스텐션은 태그에 해당하는 소스 코드에서 컴파일돼요.
- 시맨틱 버전 관리 시맨틱이 적용돼요. 자세한 내용은 Semantic Versioning 명세를 참고해요.
- 익스텐션은 새 기능을 nightly 빌드에서 테스트한 뒤 릴리스로 묶어
core저장소에 푸시하는 릴리스 주기를 따라요. - 각 릴리스에 무엇이 추가됐는지 설명하는 릴리스 노트가 제공되어 버전 간 차이를 이해하기 쉬워야 해요.
안정 익스텐션 (Stable Extensions)
Stable 익스텐션은 익스텐션 안정성의 마지막 단계예요. x>0인 vx.y.z 형식의 안정 SemVer로 표시돼요.
예를 들어 이 글을 쓰는 시점에 parquet 익스텐션의 버전은 v1.0.0 버전의 stable 익스텐션이에요.
stable 형식의 버전 번호를 가진 익스텐션에서 기대할 수 있는 건? 기본적으로 pre-release 익스텐션과 같지만, 이제 더 엄격한 SemVer 시맨틱이 적용돼요: 익스텐션의 API는 이제 안정적이어야 하고, 메이저 버전이 올라갈 때만 하위 호환되지 않는 방식으로 바뀌어요. 자세한 내용은 SemVer 명세를 참고해요.
Pre-Release 및 Stable Core Extensions의 릴리스 주기
일반적으로 익스텐션의 릴리스 주기는 안정성 수준에 따라 달라져요. unstable 익스텐션은 종종 DuckDB의 릴리스 주기와 동기화되지만, DuckDB 릴리스 사이에 조용히 업데이트될 수도 있어요. pre-release와 stable 익스텐션은 자신만의 릴리스 주기를 따라요. 이는 DuckDB 릴리스와 일치할 수도 있고 아닐 수도 있어요. 특정 익스텐션의 릴리스 주기에 대해 더 알고 싶다면 해당 익스텐션의 문서나 GitHub 페이지를 참고해요. 일반적으로 pre-release와 stable 익스텐션은 릴리스를 GitHub 릴리스로 문서화하며, 그 예를 delta 익스텐션에서 볼 수 있어요.
마지막으로 작은 예외가 하나 있어요: 모든 in-tree 익스텐션은 단순히 DuckDB의 릴리스 주기를 따라요.
Nightly 빌드 (Nightly Builds)
DuckDB 자체처럼 DuckDB의 core 익스텐션도 기능이 공식 릴리스되기 전에 시험해 볼 수 있는 nightly 또는 dev 빌드가 있어요. 이는 워크플로가 새 기능에 의존하거나, 스택이 곧 나올 버전과 호환되는지 확인해야 할 때 유용해요.
익스텐션용 nightly 빌드는 현재 DuckDB 익스텐션 바이너리가 단일 DuckDB 버전에 긴밀히 묶여 있다는 사실 때문에 약간 복잡해요. 이 긴밀한 연결 때문에 조합 폭발의 잠재적 위험이 있어요. 따라서 nightly 익스텐션 빌드와 nightly DuckDB 빌드의 모든 조합이 가능하진 않아요.
일반적으로 nightly 빌드를 사용하는 방법은 두 가지가 있어요: nightly DuckDB 빌드를 사용하거나 stable DuckDB 빌드를 사용하는 것. 두 방법의 차이를 살펴볼게요.
Stable DuckDB에서 (From Stable DuckDB)
대부분의 경우 사용자는 특정 익스텐션의 nightly 빌드에 관심이 있지만, DuckDB 자체의 nightly 빌드로 전환하길 원하진 않아요. 이러면 불안정한 코드에 대한 노출을 제한하면서 특정 최첨단 기능을 사용할 수 있어요.
이를 위해 Core Extensions는 core_nightly 저장소에 빌드를 정기적으로 푸시하는 경향이 있어요. 예를 살펴볼게요.
먼저 stable DuckDB 빌드를 설치해요.
그런 다음 nightly 익스텐션을 이렇게 설치하고 로드할 수 있어요:
INSTALL aws FROM core_nightly;
LOAD aws;
이 예시에서는 최신 nightly 빌드의 aws 익스텐션을 최신 stable 버전의 DuckDB와 함께 사용하고 있어요.
Nightly DuckDB에서 (From Nightly DuckDB)
DuckDB CI가 DuckDB 자체의 nightly 바이너리를 만들면, 그 바이너리는 특정 버전에 고정된 익스텐션 세트와 함께 배포돼요. 이 익스텐션 버전은 해당 DuckDB 빌드에 대해 테스트되지만, 최신 dev 빌드가 아닐 수 있어요. 예를 살펴볼게요.
먼저 nightly DuckDB 빌드를 설치해요. 그런 다음 예상대로 aws 익스텐션을 설치하고 로드할 수 있어요:
INSTALL aws;
LOAD aws;
익스텐션 업데이트 (Updating Extensions)
DuckDB에는 모든 익스텐션을 자동으로 최신 버전으로 업데이트하는 전용 문이 있어요. 출력은 어떤 익스텐션이 어떤 버전에서 어떤 버전으로 업데이트됐는지 사용자에게 알려 줘요. 예를 들어:
UPDATE EXTENSIONS;
| extension_name | repository | update_result | previous_version | current_version |
|---|---|---|---|---|
| httpfs | core | NO_UPDATE_AVAILABLE | 70fd6a8a24 | 70fd6a8a24 |
| delta | core | UPDATED | d9e5cc1 | 04c61e4 |
| azure | core | NO_UPDATE_AVAILABLE | 49b63dc | 49b63dc |
| aws | core_nightly | NO_UPDATE_AVAILABLE | 42c78d3 | 42c78d3 |
DuckDB는 각 익스텐션의 소스 저장소에서 업데이트를 찾아요. 따라서 익스텐션이 core_nightly에서 설치됐다면 최신 nightly 빌드로 업데이트돼요.
업데이트 문에 업데이트할 특정 익스텐션 목록을 제공할 수도 있어요:
UPDATE EXTENSIONS (httpfs, azure);
| extension_name | repository | update_result | previous_version | current_version |
|---|---|---|---|---|
| httpfs | core | NO_UPDATE_AVAILABLE | 70fd6a8a24 | 70fd6a8a24 |
| azure | core | NO_UPDATE_AVAILABLE | 49b63dc | 49b63dc |
대상 DuckDB 버전 (Target DuckDB Version)
현재 익스텐션은 컴파일될 때 특정 DuckDB 버전에 묶여요. 이는 예를 들어 0.10.3 버전용으로 컴파일된 익스텐션 바이너리가 1.0.0 버전에서는 동작하지 않는다는 뜻이에요. 대부분의 경우 이는 문제를 일으키지 않고 완전히 투명해요. DuckDB가 자신의 버전에 맞는 올바른 바이너리를 자동으로 설치하도록 보장하기 때문이에요. 익스텐션 개발자에게 이는 새 버전의 DuckDB가 릴리스될 때마다 새 바이너리를 만들어야 함을 의미해요. 다만 DuckDB는 이를 상당히 간단하게 만드는 익스텐션 템플릿을 제공해요.
In-Tree vs. Out-of-Tree
원래 DuckDB 익스텐션은 DuckDB 메인 저장소인 github.com/duckdb/duckdb에만 존재했어요. 이런 익스텐션을 in-tree라고 해요. 이후 out-of-tree 익스텐션 개념이 추가됐는데, 익스텐션이 자신만의 저장소로 분리된 것을 out-of-tree라고 불러요.
사용자 관점에서 보통 눈에 띄는 차이는 없지만, 버전 관리와 관련된 사소한 차이가 몇 가지 있어요:
- in-tree 익스텐션은 고유한 버전을 갖는 대신 DuckDB의 버전을 사용해요
- in-tree 익스텐션은 전용 릴리스 노트가 없고, 그 변경 사항은 일반 DuckDB 릴리스 노트에 반영돼요
- core out-of-tree 익스텐션은 보통
github.com/duckdb/duckdb-⟨extension_name⟩이름의 저장소에 있지만 이름은 다를 수 있어요. 자세한 내용은 core 익스텐션의 전체 목록을 참고해요.