Säkerhetskopia, export och import
Allt som Control Center kan kopiera, lämna över eller ta över, och den exakta formen på varje artefakt. För att faktiskt ta en säkerhetskopia, se Säkerhetskopiera och återställ; för varför beständigheten är uppdelad så här, se Arbetsytor och isolering.
Artefakter
Avsnitt med rubriken “Artefakter”Det finns tre artefakter för databaskopior, med olika omfattning och olika regler för borttagning.
| Artefakt | Skrivs av | Form | Omfattar |
|---|---|---|---|
| Installationsögonblicksbild | server.backupNow |
En tidsstämplad katalog | Varje databas i installationen |
| Säkerhetskopia av arbetsyta | pipelinen Workspace backup |
Tidsstämplad katalog med en .db |
En arbetsytas databas |
| Arbetsytaexport | workspace.export |
En enda .db-fil |
En arbetsytas databas |
Alla skrivs med SQLite VACUUM INTO, som är säkert mot en levande WAL-databas:
det tar en lästransaktion, producerar en defragmenterad och transaktionellt konsekvent
kopia och kräver aldrig att servern stoppas.
Ögonblicksbildens struktur
Avsnitt med rubriken “Ögonblicksbildens struktur”<dataDir>/backups/2026-07-28T09-12-33-000Z/ manifest.json global.db <workspaceId>/workspace.db one directory per workspaceStrukturen speglar den levande datakatalogen exakt, vilket är det som gör att en
återställning av en installation blir en tillbakakopiering i stället för en
översättning. Katalognamnet är UTC-tidsstämpeln med : och . utbytta mot -, så det
är filsystemssäkert på Windows och sorteras kronologiskt som en vanlig sträng.
Schemalagda säkerhetskopior av arbetsytor ligger separat under
<dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db.
De innehåller inget manifest och ingen global.db och är inte
installationsögonblicksbilder. Veckopipelinens bevarandesteg tar bara bort
säkerhetskopior från sin egen arbetsyta som är äldre än den konfigurerade åldern
(30 dagar som standard); manuellt skapade installationsögonblicksbilder roteras
aldrig av det steget. server.listBackups listar bara
installationsögonblicksbilder, även ofullständiga sådana.
manifest.json
Avsnitt med rubriken “manifest.json”| Fält | Typ | Betydelse |
|---|---|---|
version |
int | Manifestets formatversion. För närvarande 1 |
created_at |
ISO-8601 UTC | När ögonblicksbilden togs |
global.file |
string | Alltid global.db |
global.schema_version |
int | GlobalDatabase-schemaversionen vid kopieringstillfället |
global.bytes |
int | Storleken på den skrivna global.db |
workspace_schema_version |
int | Den WorkspaceDatabase-schemaversion som delas av varje arbetsytefil |
workspaces[] |
array | En post per fångad arbetsyta |
workspaces[].workspace_id |
string | Arbetsytan som den här filen innehåller |
workspaces[].file |
string | Sökväg relativt ögonblicksbildens rot, <workspaceId>/workspace.db |
workspaces[].bytes |
int | Storleken på den filen |
skipped_workspaces[] |
array of string | Arbetsytor som säkerhetskopian inte kunde fånga |
En arbetsyta hoppas över när den är registrerad men aldrig har skrivits till (så det
finns ingen fil ännu), eller när dess VACUUM INTO misslyckades. Hur som helst
slutförs ändå ögonblicksbilden, och manifestet namnger det som saknas.
Fullständighet
Avsnitt med rubriken “Fullständighet”server.listBackups rapporterar en complete-flagga per ögonblicksbild. Den är falsk
när manifestet saknas eller inte går att tolka, när global.db saknas, eller när
manifestet namnger en arbetsytefil som inte finns på disken.
En ofullständig ögonblicksbild listas ändå, för en ögonblicksbild som en operatör inte
kan se är en ögonblicksbild som operatören tror sig ha. När manifestet inte går att
läsa faller listningen tillbaka på själva strukturen och rapporterar de
<workspaceId>/workspace.db-filer den hittar – de kan fortfarande tas över var för sig
via workspace.import, även om ögonblicksbilden som helhet inte kan återställa en
installation.
Vad en säkerhetskopia inte innehåller
Avsnitt med rubriken “Vad en säkerhetskopia inte innehåller”Båda artefakterna är enbart databaser. En arbetsytekatalog innehåller mer än sin databas, och inget av resten följer med:
| Sökväg | I en ögonblicksbild? | I en arbetsytaexport? |
|---|---|---|
global.db |
Ja | Nej |
<workspaceId>/workspace.db |
Ja | Ja (den är filen) |
<workspaceId>/blobs/ |
Nej | Nej |
<workspaceId>/skills/ |
Nej | Nej |
<workspaceId>/agents/ |
Nej | Nej |
<workspaceId>/chat_credentials/ |
Nej | Nej |
<workspaceId>/spaces/<spaceId>/ |
Nej | Nej |
<workspaceId>/pr_clones/ |
Nej | Nej |
secrets.json |
Nej | Nej |
models/ |
Nej | Nej |
meetings/<meetingId>/ |
Nej | Nej |
rigs/ |
Nej | Nej |
En del av det är umbärligt – spaces/ innehåller copy-on-write-worktrees som
återskapas från repona, pr_clones/ är en cache, models/ laddas ner på nytt, rigs/
är maskintillstånd. En del är det inte: blobs/ innehåller inklistrade bilder som
rader i databasen pekar på, skills/ och agents/ innehåller filerna som en agent körs
med, och secrets.json innehåller varje parkopplingsnyckel, leverantörsuppgift och
SSO-inställning i installationen. Se
Säkerhetskopiera och återställ
för att täcka resten.
Åtgärder
Avsnitt med rubriken “Åtgärder”RPC:er för säkerhetskopiering av installationen och export/import av arbetsytor är
endast för fullClient: en parkopplad telefon kan inte utlösa dem. Alla saknas helt –
inte avvisade, utan strukturellt frånvarande – på en server där ingen port för
säkerhetskopiering är inkopplad, som demoservern.
| Åtgärd | Typ | Omfattning | Minsta roll | Argument | Returnerar |
|---|---|---|---|---|---|
server.backupNow |
mutate | Installation | installationens ägare | inga | {ok, path} |
server.listBackups |
read | Installation | installationens ägare | inga | {backups: [...]} |
server.deleteBackup |
mutate | Installation | installationens ägare | name |
{ok} |
workspace.export |
read | Arbetsyta | admin |
inga | {ok, path} |
workspace.import |
mutate | Arbetsyta | owner |
source_path |
{ok, workspace_id} |
workspace.delete |
mutate | Installation* | owner |
id |
registerrad markerad som borttagen |
workspace.deletesaknar omfattning eftersom raden den markerar ligger i det globala registret; dess hanterare kontrollerar anroparens medlemskap i den namngivna arbetsytan och kräverowner.
path i varje svar är en sökväg på servervärden.
Svaret från server.listBackups
Avsnitt med rubriken “Svaret från server.listBackups”Nyast först, sorterat efter katalognamn (som är tidsstämpeln, så ordningen håller även för en ögonblicksbild vars manifest inte kunde läsas).
{ "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 utelämnas när manifestet inte kunde läsas. bytes på översta nivån är den
verkliga storleken på disken för hela katalogen, inte manifestets egen summa – frågan
en operatör som gallrar bland ögonblicksbilder ställer är vad katalogen kostar, inte vad
säkerhetskopian avsåg att skriva.
Varje workspaces[].path är exakt det som workspace.import tar som source_path. Det
är avsiktligt: “återställ den här arbetsytan från den här ögonblicksbilden” är
importåtgärden, så de två kan inte glida isär till olika behandlingar av samma fil.
Validering i workspace.import
Avsnitt med rubriken “Validering i workspace.import”Innan något ersätts öppnas kandidatfilen skrivskyddat med en kortlivad rå
SQLite-anslutning, och dess workspace_meta-rad läses.
| Villkor | Resultat |
|---|---|
Inte en läsbar SQLite-databas, eller ingen workspace_meta |
Avvisas. Ingenting rörs |
| Registrerat arbetsyte-id ≠ målet | Tillåts, loggas. Så här dupliceras en arbetsyta eller återställs under ett nytt id |
| Registrerat installations-id ≠ den här installationen | Tillåts, loggas. Dess parkopplade enheter och användar-id:n tillhör den installationen och löses inte upp här |
| Ogiltigt arbetsyte-id, eller filen finns inte | Avvisas |
Vid godkännande stängs målarbetsytans databas och tas bort från hanteraren innan filen
kopieras över den (en öppen driftanslutning håller filen och dess -wal), och öppnas
sedan igen så att beforeOpen installerar om FTS- och synkroniseringstriggarna, varefter
FTS-indexen byggs om – en importerad fils innehållstabeller är ifyllda men dess index kan
vara inaktuellt.
Överföringsvägar
Avsnitt med rubriken “Överföringsvägar”Varje åtgärd ovan talar i sökvägar på serversidan, vilket bara är ett fullständigt svar
när servern är din egen maskin. Dessa tre bär själva byten, på samma PSK-signerade kanal
som medieproxyn och blob-lagret använder. Anroparen signerar en målsträng med sin enhets
i förväg delade nyckel och skickar signaturen som s.
| Väg | Metod | Fråga | Signerat mål | Kräver |
|---|---|---|---|---|
/backup/workspace |
GET | w, d, s |
backup-workspace:<workspaceId> |
Arbetsytans admin |
/backup/snapshot |
GET | n, d, s |
backup-snapshot:<name> |
Installationens ägare |
/backup/restore |
POST | w, d, s |
backup-restore:<workspaceId> |
Arbetsytans ägare |
w är ett arbetsyte-id, n ett namn på en ögonblicksbildskatalog, d det anropande
enhets-id:t och s signaturen. n löses upp mot listan över säkerhetskopior i stället
för att fogas till backups-roten, så vägen kan inte riktas mot en katalog som listningen
inte skulle ha visat.
| Status | Orsak |
|---|---|
400 |
En obligatorisk frågeparameter saknas, eller så är en uppladdningskropp tom |
403 |
Okänd eller återkallad enhet, felaktig signatur, eller så saknar anroparen rollen |
404 |
Ingen port för säkerhetskopiering på den här värden, eller så finns inte den namngivna ögonblicksbilden/arbetsytefilen |
405 |
/backup/restore anropad med något annat än POST |
413 |
Uppladdningskroppen överstiger 8 GiB, antingen enligt angiven content-length eller enligt antalet faktiskt lästa byten |
500 |
Exporten eller arkiveringen misslyckades på serversidan |
Båda hämtningarna svarar med Cache-Control: no-store och Accept-Ranges: none. Varje
begäran skapar en färsk kopia och raderar den när den har strömmats, så ett
cachelagrat eller återupptaget svar skulle sammanfoga byten från två olika exporter till
en fil som ser giltig ut men inte är det.
/backup/snapshot returnerar <name>.zip, med poster relativa till ögonblicksbildens
rot så att uppackning återskapar manifest.json + global.db +
<workspaceId>/workspace.db. Posterna skrivs i sorterad ordning, så två arkiv av samma
ögonblicksbild är samma arkiv.
/backup/restore strömmar kroppen direkt till en mellanlagringsfil i stället för att
buffra den, begränsar den före och under läsningen och raderar den mellanlagrade filen på
varje väg ut, även vid en avvisning.
Sökvägar och gränser
Avsnitt med rubriken “Sökvägar och gränser”| Sak | Värde |
|---|---|
| Ögonblicksbilder | <dataDir>/backups/<timestamp>/ |
| Schemalagda säkerhetskopior av arbetsytor | <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db |
| Arbetsytaexporter | <dataDir>/backups/exports/<workspaceId>-<timestamp>.db |
| Mellanlagring för överföringar | <dataDir>/backups/transfer/ – en arbetsbänk som städas av vägen som skriver till den |
| Ögonblicksbildens arkivnamn | <snapshot directory name>.zip |
| Övre gräns för uppladdning | 8 GiB per POST /backup/restore |
| Bevarande | Installationsögonblicksbilder: manuell borttagning. Säkerhetskopior av arbetsytor: veckopipeline, 30 dagar som standard |
Katalogerna exports/, transfer/ och workspace-backups/ är inte
installationsögonblicksbilder och utesluts från server.listBackups. Bara den sista
katalogen har schemalagt bevarande; att radera en installationsögonblicksbild kräver
installationens ägares uttryckliga åtgärd.
- Säkerhetskopiera och återställ — recepten som de här åtgärderna hör till
- Arbetsytor och isolering — varför en arbetsyta är en fil
cc_serverCLI — datakatalogen som de här sökvägarna ligger i- Routkarta — var gränssnittet håller till
- Arkitektur — klient/server-delningen som sökvägarna följer