콘텐츠로 이동

백업, 내보내기, 가져오기

Control Center가 복사하고, 넘겨주고, 받아들일 수 있는 모든 것과 각 산출물의 정확한 형태입니다. 실제로 백업을 뜨려면 백업 및 복원을, 영속성이 이렇게 나뉜 이유는 워크스페이스와 격리를 참고하세요.

범위와 삭제 정책이 서로 다른 데이터베이스 사본 산출물이 세 가지 있습니다.

산출물 작성 주체 형태 포함 범위
설치 스냅샷 server.backupNow 타임스탬프가 붙은 디렉터리 설치의 모든 데이터베이스
워크스페이스 백업 Workspace backup 파이프라인 .db 하나를 담은 타임스탬프 디렉터리 워크스페이스 하나의 데이터베이스
워크스페이스 내보내기 workspace.export .db 파일 하나 워크스페이스 하나의 데이터베이스

모두 SQLite VACUUM INTO로 작성되며, 이는 실행 중인 WAL 데이터베이스에도 안전합니다. 읽기 트랜잭션을 열고, 조각 모음된 트랜잭션 일관성 사본을 만들며, 서버를 중단할 필요가 전혀 없습니다.

<dataDir>/backups/2026-07-28T09-12-33-000Z/
manifest.json
global.db
<workspaceId>/workspace.db one directory per workspace

이 레이아웃은 실제 데이터 디렉터리를 그대로 비추므로, 설치 복원이 변환이 아니라 되복사하는 일이 됩니다. 디렉터리 이름은 :와 .를 -로 바꾼 UTC 타임스탬프이므로, Windows에서 파일 시스템에 안전하고 일반 문자열로도 시간순으로 정렬됩니다.

예약된 워크스페이스 백업은 <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db에 따로 있습니다. 여기에는 매니페스트나 global.db가 없으며 설치 스냅샷도 아닙니다. 주간 파이프라인의 보존 단계는 구성된 기간(기본값 30일)보다 오래된 자기 워크스페이스의 백업만 제거합니다. 수동으로 만든 설치 스냅샷은 그 단계에서 순환 삭제되는 일이 없습니다. server.listBackups는 불완전한 것까지 포함해 설치 스냅샷만 나열합니다.

필드 유형 의미
version int 매니페스트 형식 버전. 현재 1
created_at ISO-8601 UTC 스냅샷을 생성한 시각
global.file string 항상 global.db
global.schema_version int 캡처 시점의 GlobalDatabase 스키마 버전
global.bytes int 작성된 global.db의 크기
workspace_schema_version int 모든 워크스페이스 파일이 공유하는 WorkspaceDatabase 스키마 버전
workspaces[] array 캡처한 워크스페이스마다 하나의 항목
workspaces[].workspace_id string 이 파일이 담고 있는 워크스페이스
workspaces[].file string 스냅샷 루트 기준 상대 경로, <workspaceId>/workspace.db
workspaces[].bytes int 그 파일의 크기
skipped_workspaces[] array of string 백업이 캡처하지 못한 워크스페이스

워크스페이스는 등록되어 있지만 한 번도 기록된 적이 없거나(따라서 아직 파일이 없거나), VACUUM INTO가 실패했을 때 건너뜁니다. 어느 쪽이든 스냅샷은 그대로 완료되며, 매니페스트에 무엇이 빠졌는지 적힙니다.

server.listBackups는 스냅샷마다 complete 플래그를 보고합니다. 매니페스트가 없거나 파싱할 수 없을 때, global.db가 없을 때, 또는 매니페스트가 디스크에 없는 워크스페이스 파일을 가리킬 때 false입니다.

불완전한 스냅샷도 계속 나열됩니다. 운영자가 볼 수 없는 스냅샷은 가지고 있다고 믿는 스냅샷이기 때문입니다. 매니페스트를 읽을 수 없으면 목록은 레이아웃 자체로 폴백하여 찾아낸 <workspaceId>/workspace.db 파일을 보고합니다. 이런 파일들은 스냅샷 전체로는 설치를 복원할 수 없더라도 workspace.import로 개별적으로 받아들일 수 있습니다.

두 산출물 모두 데이터베이스만 담습니다. 워크스페이스 디렉터리는 데이터베이스보다 많은 것을 담고 있으며, 나머지는 어느 것도 함께 가지 않습니다.

경로 스냅샷에 포함? 워크스페이스 내보내기에 포함?
global.db 예 아니요
<workspaceId>/workspace.db 예 예(파일 자체입니다)
<workspaceId>/blobs/ 아니요 아니요
<workspaceId>/skills/ 아니요 아니요
<workspaceId>/agents/ 아니요 아니요
<workspaceId>/chat_credentials/ 아니요 아니요
<workspaceId>/spaces/<spaceId>/ 아니요 아니요
<workspaceId>/pr_clones/ 아니요 아니요
secrets.json 아니요 아니요
models/ 아니요 아니요
meetings/<meetingId>/ 아니요 아니요
rigs/ 아니요 아니요

그중 일부는 버려도 됩니다. spaces/는 저장소에서 다시 프로비저닝되는 copy-on-write 워크트리를 담고, pr_clones/는 캐시이며, models/는 다시 내려받고, rigs/는 머신 상태입니다. 그렇지 않은 것도 있습니다. blobs/는 데이터베이스의 행이 가리키는 붙여넣은 이미지를 담고, skills/와 agents/는 에이전트가 실행에 쓰는 파일을 담고, secrets.json은 설치의 모든 페어링 키와 공급자 자격 증명, SSO 설정을 담습니다. 나머지를 챙기는 방법은 백업 및 복원을 참고하세요.

설치 백업 RPC와 워크스페이스 내보내기/가져오기는 fullClient 전용이므로, 페어링된 휴대폰에서는 트리거할 수 없습니다. 백업 포트가 연결되지 않은 서버(예: 데모 서버)에서는 이들 모두가 아예 없습니다. 거부되는 것이 아니라 구조적으로 존재하지 않습니다.

연산 종류 범위 최소 역할 인수 반환
server.backupNow 변경 설치 설치 소유자 없음 {ok, path}
server.listBackups 읽기 설치 설치 소유자 없음 {backups: [...]}
server.deleteBackup 변경 설치 설치 소유자 name {ok}
workspace.export 읽기 워크스페이스 admin 없음 {ok, path}
workspace.import 변경 워크스페이스 owner source_path {ok, workspace_id}
workspace.delete 변경 설치* owner id 레지스트리 행이 삭제됨으로 표시됨
  • workspace.delete는 표시하는 행이 전역 레지스트리에 있으므로 범위가 없습니다. 이 연산의 핸들러는 호출자가 해당 워크스페이스의 멤버인지 확인하고 owner를 요구합니다.

모든 응답의 path는 서버 호스트의 경로입니다.

최신순이며 디렉터리 이름으로 정렬합니다(이름이 곧 타임스탬프이므로, 매니페스트를 읽을 수 없는 스냅샷에서도 순서가 유지됩니다).

{
"backups": [
{
"path": "/…/backups/2026-07-28T09-12-33-000Z",
"name": "2026-07-28T09-12-33-000Z",
"created_at": "2026-07-28T09:12:33.000Z",
"bytes": 481203712,
"complete": true,
"workspaces": [
{
"workspace_id": "w_9f2c…",
"path": "/…/backups/2026-07-28T09-12-33-000Z/w_9f2c…/workspace.db",
"bytes": 190840832
}
],
"skipped_workspace_ids": []
}
]
}

매니페스트를 읽을 수 없으면 created_at은 생략됩니다. 최상위 bytes는 매니페스트가 스스로 합한 값이 아니라 디렉터리 전체의 실제 디스크 크기입니다. 스냅샷을 정리하는 운영자가 묻는 것은 그 디렉터리가 차지하는 비용이지, 백업이 기록하려던 양이 아니기 때문입니다.

각 workspaces[].path는 workspace.import가 source_path로 받는 값과 정확히 같습니다. 이는 의도된 것으로, “이 스냅샷에서 이 워크스페이스를 복원한다”는 것이 곧 가져오기 연산이므로, 둘이 같은 파일을 다르게 취급하는 쪽으로 어긋날 수 없습니다.

무엇이든 대체되기 전에, 후보 파일을 수명이 짧은 원시 SQLite 연결로 읽기 전용으로 열고 workspace_meta 행을 읽습니다.

조건 결과
읽을 수 있는 SQLite 데이터베이스가 아니거나 workspace_meta가 없음 거부됩니다. 아무것도 건드리지 않습니다
기록된 워크스페이스 id ≠ 대상 허용되고 기록됩니다. 이렇게 해서 워크스페이스를 복제하거나 새 id로 복원합니다
기록된 설치 id ≠ 이 설치 허용되고 기록됩니다. 그 워크스페이스의 페어링된 기기와 사용자 id는 그 설치에 속하며 여기서는 해석되지 않습니다
유효하지 않은 워크스페이스 id이거나 파일이 없음 거부됩니다

받아들이면 대상 워크스페이스의 데이터베이스가 매니저에서 닫히고 제거된 뒤에 그 위로 파일이 복사되며(열려 있는 drift 연결이 파일과 그 -wal을 붙잡고 있습니다), 그다음 다시 열려 beforeOpen이 FTS와 동기화 트리거를 다시 설치하고 FTS 인덱스가 다시 작성됩니다. 가져온 파일의 콘텐츠 테이블은 채워져 있지만 인덱스는 오래되었을 수 있습니다.

위의 모든 연산은 서버 측 경로로 말하며, 이는 서버가 곧 자신의 머신일 때만 완전한 답입니다. 다음 세 가지가 바이트를 실어 나르며, 미디어 프록시와 블롭 저장소가 사용하는 것과 같은 PSK로 서명된 레인을 씁니다. 호출자는 기기의 사전 공유 키로 대상 문자열에 서명하고 그 서명을 s로 전달합니다.

라우트 메서드 쿼리 서명 대상 필요 권한
/backup/workspace GET w, d, s backup-workspace:<workspaceId> 워크스페이스 관리자
/backup/snapshot GET n, d, s backup-snapshot:<name> 설치 소유자
/backup/restore POST w, d, s backup-restore:<workspaceId> 워크스페이스 소유자

w는 워크스페이스 id, n은 스냅샷 디렉터리 이름, d는 호출 기기 id, s는 서명입니다. n은 백업 루트에 이어 붙이는 것이 아니라 백업 목록을 기준으로 해석되므로, 이 라우트를 목록에 없던 디렉터리로 겨냥할 수 없습니다.

상태 원인
400 필수 쿼리 매개변수가 없거나 업로드 본문이 비어 있음
403 알 수 없거나 해지된 기기, 잘못된 서명, 또는 호출자에게 역할이 없음
404 이 호스트에 백업 포트가 없거나, 지정한 스냅샷/워크스페이스 파일이 없음
405 /backup/restore가 POST가 아닌 다른 메서드로 호출됨
413 선언된 content-length 기준이든 실제로 읽은 바이트 기준이든 업로드 본문이 8 GiB를 초과함
500 서버 측에서 내보내기나 아카이브가 실패함

두 다운로드 모두 Cache-Control: no-store와 Accept-Ranges: none으로 응답합니다. 요청마다 새 사본을 만들어 내고 스트리밍이 끝나면 삭제하므로, 캐시되거나 재개된 응답은 서로 다른 두 내보내기의 바이트를 이어 붙여, 멀쩡해 보이지만 그렇지 않은 파일 하나를 만들게 됩니다.

/backup/snapshot은 <name>.zip을 반환하며, 항목들은 스냅샷 루트 기준 상대 경로이므로 압축을 풀면 manifest.json + global.db + <workspaceId>/workspace.db가 그대로 재현됩니다. 항목은 정렬된 순서로 기록되므로, 같은 스냅샷의 두 아카이브는 같은 아카이브입니다.

/backup/restore는 본문을 버퍼링하지 않고 곧바로 스테이징 파일로 스트리밍하며, 읽기 전과 읽는 동안 크기를 제한하고, 거부된 경우까지 포함해 나가는 모든 경로에서 스테이징된 파일을 삭제합니다.

항목 값
스냅샷 <dataDir>/backups/<timestamp>/
예약된 워크스페이스 백업 <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db
워크스페이스 내보내기 <dataDir>/backups/exports/<workspaceId>-<timestamp>.db
전송 스테이징 <dataDir>/backups/transfer/ — 작업 공간이며, 여기에 쓰는 라우트가 스윕합니다
스냅샷 아카이브 이름 <snapshot directory name>.zip
업로드 상한 POST /backup/restore당 8 GiB
보존 설치 스냅샷: 수동 삭제. 워크스페이스 백업: 주간 파이프라인, 기본 30일

exports/, transfer/, workspace-backups/ 디렉터리는 설치 스냅샷이 아니며 server.listBackups에서 제외됩니다. 마지막 디렉터리만 예약된 보존 정책을 가지며, 설치 스냅샷을 삭제하려면 설치 소유자의 명시적인 조치가 필요합니다.