Dolt 2.0: Prolly Tree와 Archive 포맷으로 SQL 데이터베이스에 Git-style 버전 관리를 넣은 방법
SQL 데이터베이스에 버전 관리가 필요한 이유
스키마 변경을 잘못 적용한 이후 "롤백해야 한다"는 상황을 한 번쯤 경험한 DBA는 안다. MySQL이나 PostgreSQL에서 롤백이란 백업에서 복원하거나, binlog를 역방향으로 재생하거나, gh-ost를 다시 실행하는 것이다. 어느 방법이든 시간이 걸리고, 두 시점 사이의 데이터를 어떻게 처리할지 결정해야 한다.
Git은 소스 코드에서 이 문제를 다르게 접근한다. 모든 커밋은 스냅샷이고, 브랜치는 비용이 없으며, diff는 즉각적이다. Dolt는 이 패러다임을 관계형 데이터베이스에 그대로 가져온 MySQL 호환 데이터베이스다.
Dolt는 2026년 5월 11일 2.0을 출시했다. 핵심 변화는 세 가지다.
- Archive 포맷 — 새 온디스크 포맷으로 스토리지 30~50% 추가 감소
- 자동 가비지 컬렉션 — 기본 활성화, 별도 GC 관리 불필요
- Adaptive Storage — TOAST 타입 지원으로 TEXT·JSON·BLOB 대형 값 최적화
- 벡터 지원(베타) — MariaDB Vector 타입, 버전 관리되는 유일한 벡터 DB
Prolly Tree: 버전 관리 가능한 스토리지 엔진의 핵심
B-tree의 문제
표준 B-tree는 제자리 갱신(in-place update)을 한다. 페이지를 열고, 값을 바꾸고, 다시 닫는다. 이전 상태는 WAL에만 남는다. 두 버전을 비교하려면 WAL을 뒤지거나 별도 스냅샷이 필요하다. 브랜칭이란 개념 자체가 없다.
Prolly Tree: 확률적 B-tree
Prolly Tree(Probabilistic B-tree)는 Noms 팀이 데이터베이스 버전 관리를 위해 설계한 콘텐츠 주소 기반 트리다.
핵심 속성은 두 가지다.
콘텐츠 주소(content address): 각 내부 노드는 자신의 내용을 해시한 값으로 식별된다. 같은 데이터는 항상 같은 해시를 갖는다. 두 트리의 루트 해시가 같으면 내용이 완전히 동일하다는 것이 보장된다.
확률적 청킹(probabilistic chunking): 노드 경계를 어디서 자를지는 내용의 롤링 해시(rolling hash)가 결정한다. 롤링 해시 값이 특정 임계값 이하로 떨어지면 새 청크가 시작된다. 임계값은 평균 4KB 청크를 만들도록 조정된다. 이 방식은 삽입 순서와 무관하게 동일한 데이터라면 항상 동일한 청크 경계가 생긴다(History Independence)는 성질을 보장한다.
구조적 공유(Structural Sharing)
값이 변경될 때 Prolly Tree는 기존 노드를 수정하지 않는다. 변경된 노드만 새로 만들고, 변경되지 않은 서브트리는 같은 해시 포인터를 재사용한다. 루트 해시만 바뀌면 새 버전이 완성된다. 브랜치 생성은 루트 해시를 하나 더 기록하는 일이므로 비용이 거의 없다.
Dolt 2.0: Archive 포맷과 스토리지 개선
기존 청크 스토어의 한계
Dolt 1.x까지 사용한 청크 스토어는 Prolly Tree 노드 하나가 하나의 청크로 저장된다. 히스토리가 깊어질수록, 특히 서로 다른 버전에서 비슷한 데이터를 많이 갖는 경우, 저장된 청크는 내용이 거의 같은데도 각각 별도로 존재한다.
Archive 포맷
Dolt 2.0의 archive 포맷은 청크들을 사전 기반 압축(dictionary compression)으로 묶는다. 비슷한 청크들을 그룹으로 모아 사전을 만들고, 각 청크는 사전 대비 델타만 저장한다. 여기에 zStd 압축을 추가해 기존 대비 30~50% 스토리지 절감이 가능하다.
Archive 포맷은 Dolt 2.0에서 기본값이며, 기존 Dolt 1.x 데이터베이스는 dolt archive 명령으로 변환할 수 있다.
자동 가비지 컬렉션(AutoGC)
Dolt 1.x에서는 삭제된 커밋이나 브랜치의 데이터가 디스크에 남아 주기적으로 dolt gc를 실행해야 했다. Dolt 2.0부터 AutoGC가 기본 활성화되어 대부분의 사용자는 GC를 신경 쓰지 않아도 된다.
Adaptive Storage (TOAST)
TEXT·JSON·BLOB 같은 대형 값을 효율적으로 처리하는 Adaptive Storage가 추가됐다. PostgreSQL의 TOAST(The Oversized-Attribute Storage Technique)와 유사하게, 큰 값은 별도 블록에 저장하고 메인 행은 포인터만 갖는다. 이로 인해 넓은 행이나 JSON 집약적 스키마에서 쿼리 성능이 개선됐다.
성능 벤치마크
Dolt 2.0 팀은 MySQL 8.0과의 비교에서 쓰기 13% 빠름, 읽기 5% 빠름을 달성했다고 발표했다. Dolt 1.x 초창기에는 MySQL 대비 2~3배 느렸음을 감안하면, 버전 관리 오버헤드를 거의 없애는 수준까지 최적화된 것이다.
SQL로 버전 관리하기
Dolt는 MySQL 프로토콜을 완전히 지원하므로 기존 MySQL 클라이언트로 접속할 수 있다. 버전 관리 기능은 시스템 테이블과 함수, 저장 프로시저로 노출된다.
핵심 SQL 인터페이스
-- 브랜치 목록 조회
SELECT * FROM dolt_branches;
-- 새 브랜치 생성
CALL dolt_branch('feature/new-schema');
-- 브랜치 전환
CALL dolt_checkout('feature/new-schema');
-- 변경 내용 스테이징 및 커밋
CALL dolt_add('orders');
CALL dolt_commit('-m', 'Add status column to orders');
-- 두 커밋 사이의 diff 조회
SELECT * FROM dolt_diff_orders
WHERE from_commit = 'abc123' AND to_commit = 'def456';
-- 특정 시점의 데이터 조회
SELECT * FROM orders AS OF 'feature/new-schema';
-- 또는
SELECT * FROM `main/orders` AS OF '2026-04-01';
-- 머지
CALL dolt_merge('feature/new-schema');
-- 커밋 히스토리
SELECT commit_hash, committer, date, message
FROM dolt_log
ORDER BY date DESC
LIMIT 10;충돌 해결
Dolt의 3-way merge는 공통 조상을 기준으로 양쪽 브랜치의 변경을 비교한다. 같은 행을 양쪽에서 수정했을 때는 dolt_conflicts 테이블에 충돌이 기록되고, 사용자가 SQL로 해결한다.
-- 충돌 확인
SELECT * FROM dolt_conflicts_orders;
-- 우리 버전으로 해결
UPDATE dolt_conflicts_orders
SET resolved = 'ours'
WHERE base_status IS NULL AND ours_status IS NOT NULL;
-- 충돌 해결 커밋
CALL dolt_commit('-m', 'Resolve merge conflicts');벡터 지원 (베타)
Dolt 2.0은 MariaDB Vector 타입을 채택해 버전 관리되는 벡터 인덱스를 제공한다. 이는 벡터를 버전 관리하는 유일한 데이터베이스라고 팀은 주장한다. ML 모델의 임베딩을 커밋 단위로 추적하거나 롤백하는 시나리오에 유용하다.
CREATE TABLE product_embeddings (
id INT PRIMARY KEY,
name TEXT,
embedding VECTOR(1536)
);
-- 특정 커밋 시점의 임베딩 조회
SELECT * FROM product_embeddings AS OF 'v1.2-baseline';언제 Dolt를 사용할 것인가
운영 체크리스트
- [ ] Dolt 2.0 설치 및 MySQL 클라이언트 연결 확인 (
dolt sql-server기동) - [ ] 기존 Dolt 1.x DB를 archive 포맷으로 변환:
dolt archive - [ ] AutoGC 동작 확인: 오래된 브랜치 삭제 후 디스크 사용량 모니터링
- [ ] 브랜치 전략 설계:
main(프로덕션),staging, 기능별 브랜치 - [ ]
dolt_diff_*뷰로 PR 리뷰 워크플로우 자동화 스크립트 작성 - [ ]
AS OF구문으로 특정 커밋 시점 데이터 재현 테스트 - [ ] DoltHub 또는 자체 호스팅 저장소와
dolt push/pull연동 설정 - [ ] 충돌 해결 절차(
dolt_conflicts_*) 팀 문서화
References
- Dolt 2.0 Release Blog — DoltHub
- Prolly Trees — Dolt Documentation
- Storage Engine — Dolt Documentation
- Version Controlled SQL Database Dolt Releases 2.0 — InfoQ
- Prolly-trees: a content-addressed B tree with structural sharing — Lobsters
- How Dolt Stores Table Data — DoltHub Blog
- How Dolt Scales to Millions of Versions, Branches, and Rows — DoltHub Blog
- Version-controlled databases using Prolly trees — LWN.net