Saltar para o conteúdo

Cópia de segurança, exportação e importação

Tudo o que o Control Center consegue copiar, entregar ou adotar, e a forma exata de cada artefacto. Para tirar efetivamente uma cópia de segurança, consulte Fazer cópia de segurança e restaurar; para perceber porque é que a persistência está dividida desta forma, consulte Espaços de trabalho e isolamento.

Existem três artefactos de cópia de base de dados, com âmbitos e políticas de eliminação diferentes.

Artefacto Escrito por Forma Abrange
Instantâneo da instalação server.backupNow Um diretório com data e hora Todas as bases de dados da instalação
Cópia de segurança do espaço de trabalho Pipeline Workspace backup Diretório com data e hora com um .db A base de dados de um espaço de trabalho
Exportação do espaço de trabalho workspace.export Um único ficheiro .db A base de dados de um espaço de trabalho

Todos são escritos com o VACUUM INTO do SQLite, que é seguro contra uma base de dados WAL em funcionamento: abre uma transação de leitura, produz uma cópia desfragmentada e transacionalmente consistente e nunca exige parar o servidor.

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

A estrutura espelha exatamente o diretório de dados em funcionamento, e é isso que faz com que restaurar uma instalação seja uma cópia de volta e não uma tradução. O nome do diretório é a data e hora UTC com : e . substituídos por -, pelo que é seguro para sistemas de ficheiros no Windows e ordena-se cronologicamente como uma cadeia simples.

As cópias de segurança agendadas de espaços de trabalho ficam à parte, em <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db. Não incluem um manifesto nem o global.db e não são instantâneos da instalação. O passo de retenção do pipeline semanal remove apenas cópias de segurança do seu próprio espaço de trabalho mais antigas do que a idade configurada (30 dias por predefinição); os instantâneos da instalação criados manualmente nunca são rodados por esse passo. O server.listBackups lista apenas instantâneos da instalação, incluindo os incompletos.

Campo Tipo Significado
version int Versão do formato do manifesto. Atualmente 1
created_at ISO-8601 UTC Quando o instantâneo foi tirado
global.file string Sempre global.db
global.schema_version int Versão do esquema do GlobalDatabase no momento da captura
global.bytes int Tamanho do global.db escrito
workspace_schema_version int Versão do esquema do WorkspaceDatabase partilhada por todos os ficheiros 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 ficheiro contém
workspaces[].file string Caminho relativo à raiz do instantâneo, <workspaceId>/workspace.db
workspaces[].bytes int Tamanho desse ficheiro
skipped_workspaces[] array de string Espaços de trabalho que a cópia de segurança não conseguiu capturar

Um espaço de trabalho é ignorado quando está registado mas nunca foi escrito (pelo que ainda não existe ficheiro) ou quando o seu VACUUM INTO falhou. De qualquer forma, o instantâneo conclui-se na mesma e o manifesto indica o que está em falta.

O server.listBackups reporta um indicador complete por instantâneo. É falso quando o manifesto está ausente ou não é analisável, quando o global.db está em falta ou quando o manifesto refere um ficheiro de espaço de trabalho que não existe no disco.

Um instantâneo incompleto continua a ser listado, porque um instantâneo que um operador não vê é um instantâneo que ele acredita ter. Quando o manifesto não é legível, a listagem recorre à própria estrutura e reporta os ficheiros <workspaceId>/workspace.db que encontrar — esses continuam a poder ser adotados individualmente através do workspace.import, ainda que o instantâneo no seu todo não consiga restaurar uma instalação.

Ambos os artefactos são apenas bases de dados. Um diretório de espaço de trabalho contém mais do que a sua base de dados, e nada do resto viaja:

Caminho Num instantâneo? Numa exportação de espaço de trabalho?
global.db Sim Não
<workspaceId>/workspace.db Sim Sim (é o ficheiro)
<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 reprovisionadas a partir dos repos, pr_clones/ é uma cache, models/ volta a ser descarregado e rigs/ é estado da máquina. Outra parte não é: blobs/ contém imagens coladas para as quais apontam linhas da base de dados, skills/ e agents/ contêm os ficheiros com que um agente é executado e secrets.json contém todas as chaves de emparelhamento, credenciais de fornecedor e definições de SSO da instalação. Consulte Fazer cópia de segurança e restaurar para cobrir o resto.

Os RPC de cópia de segurança da instalação e a exportação/importação de espaços de trabalho são exclusivos de fullClient: um telefone emparelhado não os consegue acionar. Todos eles estão totalmente ausentes — não recusados, estruturalmente em falta — num servidor sem porta de cópia de segurança ligada, como o servidor de demonstração.

Op Tipo Âmbito Papel mínimo Argumentos Devolve
server.backupNow mutação Instalação proprietário da instalação nenhum {ok, path}
server.listBackups leitura Instalação proprietário da instalação nenhum {backups: [...]}
server.deleteBackup mutação Instalação proprietário da instalação name {ok}
workspace.export leitura Espaço de trabalho admin nenhum {ok, path}
workspace.import mutação Espaço de trabalho owner source_path {ok, workspace_id}
workspace.delete mutação Instalação* owner id linha do registo marcada como eliminada
  • O workspace.delete não tem âmbito porque a linha que marca vive no registo global; o seu handler verifica a pertença do chamador ao espaço de trabalho indicado e exige owner.

O path em todas as respostas é um caminho no anfitrião do servidor.

Os mais recentes primeiro, ordenados pelo nome do diretório (que é a data e hora, pelo que a ordem se mantém mesmo para um instantâneo 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": []
}
]
}

O created_at é omitido quando o manifesto não pôde ser lido. O bytes de nível superior é o tamanho real em disco do diretório inteiro, não a soma do próprio manifesto — a pergunta que um operador a limpar instantâneos faz é quanto custa o diretório, não o que a cópia de segurança pretendia escrever.

Cada workspaces[].path é exatamente o que o workspace.import recebe como source_path. Isso é deliberado: «restaurar este espaço de trabalho a partir deste instantâneo» é a operação de importação, pelo que as duas não podem divergir para tratamentos diferentes do mesmo ficheiro.

Antes de se substituir seja o que for, o ficheiro candidato é aberto apenas para leitura com uma ligação SQLite em bruto de curta duração e a sua linha workspace_meta é lida.

Condição Resultado
Não é uma base de dados SQLite legível, ou não tem workspace_meta Recusado. Nada é tocado
Id de espaço de trabalho registado ≠ o de destino Permitido, registado. É assim que um espaço de trabalho é duplicado ou restaurado com um id novo
Id de instalação registado ≠ esta instalação Permitido, registado. Os seus dispositivos emparelhados e ids de utilizador pertencem a essa instalação e não serão resolvidos aqui
Id de espaço de trabalho inválido, ou o ficheiro não existe Recusado

Após a aceitação, a base de dados do espaço de trabalho de destino é fechada e removida do gestor antes de o ficheiro ser copiado por cima dela (uma ligação do Drift aberta mantém o ficheiro e o seu -wal), e depois reaberta para que o beforeOpen volte a instalar os disparadores de FTS e de sincronização, e os índices FTS são reconstruídos — as tabelas de conteúdo de um ficheiro importado ficam preenchidas, mas o seu índice pode estar desatualizado.

Todas as operações acima falam em caminhos do lado do servidor, o que só é uma resposta completa quando o servidor é a sua própria máquina. Estas três transportam os bytes, na mesma via assinada por PSK que o proxy de multimédia e o armazenamento de blobs utilizam. O chamador assina uma cadeia de destino com a chave pré-partilhada do dispositivo e passa a assinatura como s.

Rota Método Query Alvo 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

O w é um id de espaço de trabalho, o n um nome de diretório de instantâneo, o d o id do dispositivo que chama e o s a assinatura. O n é resolvido em relação à listagem de cópias de segurança e não concatenado à raiz das cópias, pelo que a rota não pode ser apontada a um diretório que a listagem não teria mostrado.

Estado Causa
400 Falta um parâmetro de query obrigatório, ou o corpo de um envio está vazio
403 Dispositivo desconhecido ou revogado, assinatura inválida, ou o chamador não tem o papel
404 Não há porta de cópia de segurança neste anfitrião, ou o instantâneo/o ficheiro de espaço de trabalho indicado não existe
405 /backup/restore chamado com algo que não POST
413 O corpo do envio excede 8 GiB, pelo content-length declarado ou pelos bytes realmente lidos
500 A exportação ou o arquivo falhou do lado do servidor

Ambos os descarregamentos respondem com Cache-Control: no-store e Accept-Ranges: none. Cada pedido cria uma cópia nova e elimina-a assim que é transmitida em fluxo, pelo que uma resposta em cache ou retomada juntaria bytes de duas exportações diferentes num ficheiro que parece válido e não é.

O /backup/snapshot devolve <name>.zip, com entradas relativas à raiz do instantâneo, pelo que descompactar reproduz manifest.json + global.db + <workspaceId>/workspace.db. As entradas são escritas por ordem de ordenação, pelo que dois arquivos do mesmo instantâneo são o mesmo arquivo.

O /backup/restore transmite o corpo diretamente para um ficheiro de preparação em vez de o colocar em memória intermédia, limita-o antes e durante a leitura e elimina o ficheiro preparado em todos os caminhos de saída, incluindo uma recusa.

Item Valor
Instantâneos <dataDir>/backups/<timestamp>/
Cópias de segurança agendadas 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ências <dataDir>/backups/transfer/ — uma bancada de trabalho, limpa pela rota que a escreve
Nome do arquivo do instantâneo <snapshot directory name>.zip
Limite de envio 8 GiB por POST /backup/restore
Retenção Instantâneos da instalação: eliminação manual. Cópias de segurança de espaços de trabalho: pipeline semanal, predefinição de 30 dias

Os diretórios exports/, transfer/ e workspace-backups/ não são instantâneos da instalação e estão excluídos do server.listBackups. Só o último diretório tem retenção agendada; eliminar um instantâneo da instalação exige a ação explícita do proprietário da instalação.