Резервное копирование, экспорт и импорт
Всё, что 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
перечисляет только снимки установки, включая неполные.
manifest.json
Заголовок раздела «manifest.json»| Поле | Тип | Значение |
|---|---|---|
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[] |
массив строк | Рабочие пространства, которые резервная копия не смогла снять |
Рабочее пространство пропускается, когда оно зарегистрировано, но в него никогда не писали
(поэтому файла ещё нет), или когда его VACUUM INTO завершился ошибкой. В любом случае
снимок всё равно создаётся до конца, а манифест называет то, чего не хватает.
Полнота
Заголовок раздела «Полнота»server.listBackups сообщает для каждого снимка флаг complete. Он равен false, когда
манифест отсутствует или неразбираем, когда нет global.db или когда манифест называет
файл рабочего пространства, которого нет на диске.
Неполный снимок всё равно попадает в список: снимок, которого оператор не видит, — это
снимок, который он считает, что у него есть. Когда манифест не читается, список опирается
на саму структуру и сообщает о тех файлах <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/ содержит worktree с копированием при записи, которые
заново создаются из репозиториев, 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 в каждом ответе — это путь на хосте сервера.
Ответ server.listBackups
Заголовок раздела «Ответ server.listBackups»Сначала самые новые, отсортированные по имени каталога (это метка времени, поэтому порядок сохраняется даже для снимка, манифест которого не удалось прочитать).
{ "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. Это сделано намеренно: «восстановить это рабочее пространство из этого
снимка» и есть операция импорта, поэтому они не могут разойтись в разном обращении
с одним и тем же файлом.
Проверка workspace.import
Заголовок раздела «Проверка workspace.import»Прежде чем что-либо будет заменено, файл-кандидат открывается только для чтения через
недолговечное необработанное соединение SQLite, и из него читается строка workspace_meta.
| Условие | Результат |
|---|---|
Не читаемая база данных SQLite или отсутствие workspace_meta |
Отказано. Ничего не затрагивается |
| Записанный идентификатор рабочего пространства ≠ целевого | Разрешено, записывается в журнал. Так рабочее пространство дублируют или восстанавливают под новым идентификатором |
| Записанный идентификатор установки ≠ этой установки | Разрешено, записывается в журнал. Его сопряжённые устройства и идентификаторы пользователей принадлежат той установке и здесь не разрешатся |
| Недопустимый идентификатор рабочего пространства или отсутствующий файл | Отказано |
При принятии база данных целевого рабочего пространства закрывается и удаляется из менеджера
до того, как поверх неё скопируют файл (открытое соединение 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 — идентификатор рабочего пространства, n — имя каталога снимка, d — идентификатор
вызывающего устройства, s — подпись. n сопоставляется со списком резервных копий, а не
присоединяется к корню резервных копий, поэтому маршрут нельзя навести на каталог, который
список не показал бы.
| Статус | Причина |
|---|---|
400 |
Отсутствует обязательный параметр запроса или тело загрузки пусто |
403 |
Неизвестное или отозванное устройство, неверная подпись или у вызывающего нет нужной роли |
404 |
На этом хосте нет порта резервного копирования или указанный снимок либо файл рабочего пространства не существует |
405 |
/backup/restore вызван с методом, отличным от POST |
413 |
Тело загрузки превышает 8 ГиБ по объявленному content-length или по фактически прочитанным байтам |
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 |
| Потолок загрузки | 8 ГиБ на POST /backup/restore |
| Срок хранения | Снимки установки: удаление вручную. Резервные копии рабочих пространств: недельный конвейер, по умолчанию 30 дней |
Каталоги exports/, transfer/ и workspace-backups/ не являются снимками установки
и исключены из server.listBackups. Только у последнего каталога есть автоматическое
удаление по сроку хранения; удаление снимка установки требует явного действия
владельца установки.
См. также
Заголовок раздела «См. также»- Резервное копирование и восстановление — практические руководства, к которым относятся эти операции
- Рабочие пространства и изоляция — почему одно рабочее пространство — это один файл
- CLI
cc_server— каталог данных, в котором находятся эти пути - Карта маршрутов — где живёт интерфейс
- Архитектура — разделение клиента и сервера, которому следуют эти пути