브랜치
Kisenon의 카피온라이트 Postgres 브랜치 — LSN에서 포크, 수명 주기, 그리고 캐스케이드.
브랜치는 프로젝트 스토리지 내 로그 시퀀스 번호(LSN)를 가리키는 포인터입니다. 하나를 생성하는 것은 O(1) 행 삽입이며 데이터를 복사하지 않습니다. 브랜치는 쓰기를 진행함에 따라 분기하며, 델타만 저장됩니다.
모델
모든 프로젝트는 생성 시점부터 main 브랜치를 가집니다. main(또는 기존의
어떤 브랜치)에서 새 브랜치를 포크할 수 있습니다:
- HEAD에서 — 새 브랜치는 부모의 현재 LSN에서 시작합니다.
- 특정 LSN에서 — 새 브랜치는 부모의 WAL 보존 창 내 과거 LSN에서 시작합니다. 이것이 "시간 여행" 사례입니다: WAL이 여전히 보존되어 있는 한 과거의 한 지점에서 브랜치를 분기할 수 있습니다.
브랜치의 읽기는 브랜치가 분기할 때까지 부모의 페이지로 떨어집니다. 쓰기는 델타만 기록합니다. 그 결과:
- 작은 브랜치 열 개가 있는 100 GB 프로젝트는 총 ~100 GB로 청구됩니다.
- 브랜치를 생성하는 것은 1초 미만입니다.
- 브랜치는 일회용입니다. 파괴적인 마이그레이션을 실행하고 브랜치를 버리면 부모는 손대지 않은 채 남습니다.
명명
브랜치 이름은 사용자에게 보이는 레이블이며, 부모 프로젝트로 범위가 지정됩니다. 제약 조건은 프로젝트 이름과 일치합니다:
- 1–63자.
^[a-zA-Z][a-zA-Z0-9_-]*$.- 프로젝트 내에서 고유.
내부 브랜치 id(br_<24 hex>)가 안정적인 참조입니다. API에 대해 스크립팅할
때는 이름이 아니라 id를 사용하세요. 이름은 변경될 수 있습니다.
상태 머신
브랜치는 다음을 거쳐 전이합니다:
creating → ready → deleting → deleted- creating — 컨트롤 플레인이 브랜치를 스토리지 계층에 등록하는 중입니다. 일반적으로 1초 미만이며, 스토리지가 부하를 받으면 더 길어집니다.
- ready — 브랜치를 엔드포인트에 연결하고 쓰기를 받을 수 있습니다.
- deleting — 캐스케이드 진행 중: 이 브랜치의 모든 엔드포인트가 중지되고 제거되는 중입니다.
- deleted — 종료 상태. 행은 감사를 위해 짧은 기간 동안 보존된 다음 가비지 컬렉션됩니다.
CLI는 모든 브랜치의 현재 상태를 보여줍니다:
keon branches list --project <project-id>생성
keon branches create --project <project-id> --name my-feature --parent main과거 LSN에서 브랜치를 만들려면 --parent-lsn <lsn>을 전달하세요:
keon branches create \
--project <project-id> \
--name pre-migration \
--parent main \
--parent-lsn 0/1A2B3C4DLSN은 프로젝트의 WAL 보존 창 내에 있어야 합니다. 그 너머로 컴팩션되었다면 브랜치 생성이 실패합니다.
삭제
브랜치를 삭제하면 그에 연결된 모든 엔드포인트로 캐스케이드됩니다:
- 브랜치의 모든 엔드포인트가 중지되고 제거됩니다.
- 브랜치 자체가 철거됩니다.
- 스토리지는 pageserver 컴팩션에 의해 비동기적으로 회수됩니다.
keon branches delete <branch-id>프로젝트의 main 브랜치는 삭제할 수 없습니다 — 대신 프로젝트를
삭제하세요. 자식이 있더라도 다른 브랜치는 삭제할 수 있습니다. 이 경우
자식은 삭제 LSN에서 삭제된 브랜치의 부모로 재부모화됩니다.
재설정 및 복원
콘솔의 브랜치 상세 페이지에서 ⋯ 동작 메뉴는 루트가 아닌 모든 브랜치에 대해 두 가지 재포크 작업을 노출합니다:
- 부모로 재설정 — 브랜치를 부모의 현재 HEAD에서 재포크합니다. 원래 포크 이후 브랜치에서 이루어진 모든 쓰기가 폐기됩니다. 브랜치의 엔드포인트는 교체 중 잠시 일시 중지됩니다.
- 특정 시점으로 복원 — 선택한 LSN 또는 UTC 타임스탬프(RFC 3339)에서 브랜치를 재포크합니다. 그 시점 이후의 쓰기는 폐기됩니다.
둘 다 비동기적으로 실행됩니다: 콘솔이 요청을 발행하고, 재포크가 완료되면
브랜치가 ready로 돌아갑니다. 루트(main) 브랜치는 재설정할 수 없습니다 —
재설정할 부모가 없습니다.
스냅샷
스냅샷은 특정 시점의 LSN을 고정하여 WAL 보존 한계를 넘어서도 복원 가능하게 유지합니다. 스냅샷이 없으면 복원 대상은 그 WAL이 여전히 보존되어 있는 동안에만 도달할 수 있지만, 스냅샷은 그 지점을 무기한 주소 지정 가능하게 유지합니다.
브랜치 상세 페이지의 스냅샷 탭은 브랜치의 스냅샷을 나열하고 새로 하나를 캡처할 수 있게 합니다. 각 행은 다음을 제공합니다:
- 복원 — 스냅샷의 고정된 LSN에서 브랜치를 재포크합니다.
- 삭제 — 스냅샷을 드롭합니다(기저 LSN은 더 이상 고정되지 않으며 컴팩션에 의해 회수될 수 있습니다).