Backup, exportação e importação
Tudo o que o Control Center consegue copiar, entregar ou adotar, e a forma exata de cada artefato. Para de fato fazer um backup, veja Fazer backup e restaurar; para entender por que a persistência está dividida assim, veja Espaços de trabalho e isolamento.
Artefatos
Seção intitulada “Artefatos”Existem três artefatos de cópia de banco de dados, com escopos e políticas de exclusão diferentes.
| Artefato | Escrito por | Forma | Cobre |
|---|---|---|---|
| Snapshot da instalação | server.backupNow |
Um diretório com carimbo de data/hora | Todos os bancos de dados da instalação |
| Backup do espaço de trabalho | pipeline Workspace backup |
Diretório com carimbo de data/hora e um .db |
O banco de dados de um espaço de trabalho |
| Exportação do espaço de trabalho | workspace.export |
Um arquivo .db único |
O banco de dados de um espaço de trabalho |
Todos são gravados com VACUUM INTO do SQLite, que é seguro em relação a um banco de
dados WAL em uso: ele faz uma transação de leitura, produz uma cópia desfragmentada e
transacionalmente consistente e nunca exige parar o servidor.
Estrutura do snapshot
Seção intitulada “Estrutura do snapshot”<dataDir>/backups/2026-07-28T09-12-33-000Z/ manifest.json global.db <workspaceId>/workspace.db one directory per workspaceO layout espelha exatamente o diretório de dados em uso, e é isso que faz restaurar uma
instalação ser uma cópia de volta, e não uma tradução. O nome do diretório é o carimbo de
data/hora UTC com : e . substituídos por -, então é seguro para sistemas de arquivos
no Windows e ordena cronologicamente como uma string simples.
Os backups agendados de espaços de trabalho ficam separados em
<dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db.
Eles não incluem manifesto nem global.db e não são snapshots da instalação.
A etapa de retenção do pipeline semanal remove apenas backups do próprio espaço de
trabalho mais antigos que a idade configurada (30 dias por padrão); snapshots da
instalação criados manualmente nunca são rotacionados por essa etapa. server.listBackups
lista apenas snapshots da instalação, inclusive os incompletos.
manifest.json
Seção intitulada “manifest.json”| Campo | Tipo | Significado |
|---|---|---|
version |
int | Versão do formato do manifesto. Atualmente 1 |
created_at |
ISO-8601 UTC | Quando o snapshot foi tirado |
global.file |
string | Sempre global.db |
global.schema_version |
int | Versão do esquema de GlobalDatabase no momento da captura |
global.bytes |
int | Tamanho do global.db gravado |
workspace_schema_version |
int | Versão do esquema de WorkspaceDatabase compartilhada por todo arquivo de espaço de trabalho |
workspaces[] |
array | Uma entrada por espaço de trabalho capturado |
workspaces[].workspace_id |
string | O espaço de trabalho que este arquivo contém |
workspaces[].file |
string | Caminho relativo à raiz do snapshot, <workspaceId>/workspace.db |
workspaces[].bytes |
int | Tamanho desse arquivo |
skipped_workspaces[] |
array of string | Espaços de trabalho que o backup não conseguiu capturar |
Um espaço de trabalho é ignorado quando está registrado, mas nunca foi gravado (então
ainda não existe arquivo), ou quando o VACUUM INTO dele falhou. De qualquer forma o
snapshot ainda é concluído e o manifesto nomeia o que está faltando.
Completude
Seção intitulada “Completude”server.listBackups informa um sinalizador complete por snapshot. Ele é falso quando o
manifesto está ausente ou não pode ser interpretado, quando falta o global.db ou quando
o manifesto nomeia um arquivo de espaço de trabalho que não está no disco.
Um snapshot incompleto ainda é listado, porque um snapshot que o operador não consegue ver
é um snapshot que ele acredita ter. Quando o manifesto não pode ser lido, a listagem
recorre ao próprio layout e informa os arquivos <workspaceId>/workspace.db que
encontrar — eles continuam podendo ser adotados individualmente por workspace.import,
ainda que o snapshot como um todo não consiga restaurar uma instalação.
O que um backup não contém
Seção intitulada “O que um backup não contém”Os dois artefatos são apenas bancos de dados. Um diretório de espaço de trabalho contém mais do que o banco de dados dele, e nada do restante viaja:
| Caminho | Em um snapshot? | Em uma exportação de espaço de trabalho? |
|---|---|---|
global.db |
Sim | Não |
<workspaceId>/workspace.db |
Sim | Sim (ele é o arquivo) |
<workspaceId>/blobs/ |
Não | Não |
<workspaceId>/skills/ |
Não | Não |
<workspaceId>/agents/ |
Não | Não |
<workspaceId>/chat_credentials/ |
Não | Não |
<workspaceId>/spaces/<spaceId>/ |
Não | Não |
<workspaceId>/pr_clones/ |
Não | Não |
secrets.json |
Não | Não |
models/ |
Não | Não |
meetings/<meetingId>/ |
Não | Não |
rigs/ |
Não | Não |
Parte disso é descartável — spaces/ contém worktrees copy-on-write que são
reprovisionados a partir dos repos, pr_clones/ é um cache, models/ é baixado de novo,
rigs/ é estado da máquina. Parte não é: blobs/ contém imagens coladas para as quais
linhas do banco de dados apontam, skills/ e agents/ contêm os arquivos com que um
agente roda, e secrets.json contém todas as chaves de emparelhamento, credenciais de
provedor e configurações de SSO da instalação. Veja
Fazer backup e restaurar
para cobrir o restante.
Operações
Seção intitulada “Operações”Os RPCs de backup da instalação e a exportação/importação de espaço de trabalho são
exclusivos de fullClient: um telefone emparelhado não consegue acioná-los. Todos eles
estão totalmente ausentes — não recusados, mas estruturalmente inexistentes — em um
servidor sem porta de backup configurada, como o servidor de demonstração.
| Op | Tipo | Escopo | Função mínima | Argumentos | Retorna |
|---|---|---|---|---|---|
server.backupNow |
mutate | Instalação | proprietário da instalação | nenhum | {ok, path} |
server.listBackups |
read | Instalação | proprietário da instalação | nenhum | {backups: [...]} |
server.deleteBackup |
mutate | Instalação | proprietário da instalação | name |
{ok} |
workspace.export |
read | Espaço de trabalho | admin |
nenhum | {ok, path} |
workspace.import |
mutate | Espaço de trabalho | owner |
source_path |
{ok, workspace_id} |
workspace.delete |
mutate | Instalação* | owner |
id |
linha do registro marcada como excluída |
workspace.deletenão tem escopo porque a linha que ele marca vive no registro global; o handler dele verifica a associação do chamador ao espaço de trabalho nomeado e exigeowner.
path em toda resposta é um caminho no host do servidor.
Resposta de server.listBackups
Seção intitulada “Resposta de server.listBackups”Do mais recente para o mais antigo, ordenado pelo nome do diretório (que é o carimbo de data/hora, então a ordem se mantém mesmo para um snapshot cujo manifesto não pôde ser lido).
{ "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 é omitido quando o manifesto não pôde ser lido. O bytes do nível superior é
o tamanho real em disco do diretório inteiro, e não a soma do próprio manifesto — a
pergunta que um operador que faz poda de snapshots está fazendo é quanto o diretório ocupa,
e não quanto o backup pretendia gravar.
Cada workspaces[].path é exatamente o que workspace.import recebe como source_path.
Isso é deliberado: “restaurar este espaço de trabalho a partir deste snapshot” é a
operação de importação, então as duas não podem divergir em tratamentos diferentes do
mesmo arquivo.
Validação de workspace.import
Seção intitulada “Validação de workspace.import”Antes de qualquer coisa ser substituída, o arquivo candidato é aberto somente para leitura
com uma conexão SQLite bruta de vida curta e a linha workspace_meta dele é lida.
| Condição | Resultado |
|---|---|
Não é um banco de dados SQLite legível, ou não tem workspace_meta |
Recusado. Nada é tocado |
| Id de espaço de trabalho registrado ≠ o destino | Permitido, registrado em log. É assim que se duplica ou restaura um espaço de trabalho sob um id novo |
| Id de instalação registrado ≠ esta instalação | Permitido, registrado em log. Os dispositivos emparelhados e ids de usuário dele pertencem àquela instalação e não serão resolvidos aqui |
| Id de espaço de trabalho inválido, ou arquivo inexistente | Recusado |
Quando aceito, o banco de dados do espaço de trabalho de destino é fechado e removido do
gerenciador antes de o arquivo ser copiado por cima dele (uma conexão de drift aberta
mantém o arquivo e o -wal dele), e depois reaberto para que beforeOpen reinstale os
gatilhos de FTS e de sincronização, e os índices de FTS são reconstruídos — as tabelas de
conteúdo de um arquivo importado ficam preenchidas, mas o índice dele pode estar
desatualizado.
Rotas de transferência
Seção intitulada “Rotas de transferência”Toda operação acima fala em caminhos do lado do servidor, o que é uma resposta completa
apenas quando o servidor é a sua própria máquina. Estas três carregam os bytes, na mesma
via assinada por PSK que o proxy de mídia e o armazenamento de blobs usam. O chamador
assina uma string de destino com a chave pré-compartilhada do dispositivo e passa a
assinatura como s.
| Rota | Método | Query | Destino assinado | Exige |
|---|---|---|---|---|
/backup/workspace |
GET | w, d, s |
backup-workspace:<workspaceId> |
admin do espaço de trabalho |
/backup/snapshot |
GET | n, d, s |
backup-snapshot:<name> |
proprietário da instalação |
/backup/restore |
POST | w, d, s |
backup-restore:<workspaceId> |
proprietário do espaço de trabalho |
w é um id de espaço de trabalho, n é um nome de diretório de snapshot, d é o id do
dispositivo que chama e s é a assinatura. n é resolvido contra a listagem de backups
em vez de ser concatenado à raiz de backups, então a rota não pode ser apontada para um
diretório que a listagem não teria mostrado.
| Status | Causa |
|---|---|
400 |
Falta um parâmetro de query obrigatório, ou o corpo de um upload está vazio |
403 |
Dispositivo desconhecido ou revogado, assinatura inválida, ou o chamador não tem a função |
404 |
Nenhuma porta de backup neste host, ou o snapshot/arquivo de espaço de trabalho nomeado não existe |
405 |
/backup/restore chamado com qualquer coisa diferente de POST |
413 |
O corpo do upload excede 8 GiB, pelo content-length declarado ou pelos bytes realmente lidos |
500 |
A exportação ou o arquivamento falhou no lado do servidor |
Os dois downloads respondem Cache-Control: no-store com Accept-Ranges: none. Cada
requisição cria uma cópia nova e a exclui depois de transmitida, então uma resposta em
cache ou retomada juntaria bytes de duas exportações diferentes em um único arquivo que
parece válido e não é.
/backup/snapshot retorna <name>.zip, com entradas relativas à raiz do snapshot, de modo
que descompactar reproduz manifest.json + global.db + <workspaceId>/workspace.db.
As entradas são gravadas em ordem classificada, então dois arquivos compactados do mesmo
snapshot são o mesmo arquivo.
/backup/restore transmite o corpo direto para um arquivo de preparação em vez de
colocá-lo em buffer, limita o tamanho antes e durante a leitura, e exclui o arquivo
preparado em todas as saídas, inclusive numa recusa.
Caminhos e limites
Seção intitulada “Caminhos e limites”| Item | Valor |
|---|---|
| Snapshots | <dataDir>/backups/<timestamp>/ |
| Backups agendados de espaços de trabalho | <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db |
| Exportações de espaços de trabalho | <dataDir>/backups/exports/<workspaceId>-<timestamp>.db |
| Preparação de transferência | <dataDir>/backups/transfer/ — uma bancada de trabalho, varrida pela rota que a grava |
| Nome do arquivo do snapshot | <snapshot directory name>.zip |
| Teto de upload | 8 GiB por POST /backup/restore |
| Retenção | Snapshots da instalação: exclusão manual. Backups de espaços de trabalho: pipeline semanal, 30 dias por padrão |
Os diretórios exports/, transfer/ e workspace-backups/ não são snapshots da
instalação e ficam excluídos de server.listBackups. Apenas o último diretório tem
retenção agendada; excluir um snapshot da instalação exige uma ação explícita do
proprietário da instalação.
Veja também
Seção intitulada “Veja também”- Fazer backup e restaurar — as receitas às quais estas operações pertencem
- Espaços de trabalho e isolamento — por que um espaço de trabalho é um arquivo
- CLI do
cc_server— o diretório de dados em que estes caminhos ficam - Mapa de rotas — onde a UI fica
- Arquitetura — a divisão cliente/servidor que os caminhos seguem