Hopp til innhold

Oppgradere uten nedetid

Oppgrader en selvdrevet Quire uten nedetid.

Vis som Markdown

Reglene står i docs/architecture/23-ops.md seksjon 7 og docs/architecture/07-data.md seksjon 4.1. Dette er prosedyren.

Garantien som gjør det trygt

Utgivelse R kjører korrekt mot skjema R og skjema R minus én. Hver skjemendring deles i utvide, overgang og kontrakt:

  1. Utvid: legg til den nye kolonnen, tabellen eller indeksen. Gammel kode ignorerer den.
  2. Overgang, i minst én utgivelse: ny kode skriver begge former og leser den nye; en gjenopptakbar jobb etterfyller gamle rader.
  3. Kontrakt: fjern den gamle formen, i en senere utgivelse, alene.

Så i hvert øyeblikk av en rullerende oppgradering kan gamle og nye prosesser dele én database. Det finnes ingen nedmigreringer: en migrering som fjernet en kolonne for en time siden kan ikke gi tilbake radene skrevet i den timen.

schema-compat-CI-jobben sjekker garantien på hver utgivelse ved å kjøre forrige utgivelses tester mot det nye skjemaet.

Før du starter

  1. Les utgivelsesnotatene. En utgivelse som trenger et vedlikeholdsvindu sier det, med anslaget; høyst ett per utgivelse.
  2. Kjør gjenopprettingsøvelsen, eller bekreft at den kjørte grønt for denne utgivelsen (backup-restore.md). En mislykket øvelse blokkerer oppgraderingen.
  3. Ta en basesikkerhetskopi: docker compose -f docker/compose.yaml --profile backup run --rm backup.

Docker Compose, én vert

export QUIRE_RELEASE=2026.10.0            # or set it in docker/.env
docker compose -f docker/compose.yaml pull   # or build
docker compose -f docker/compose.yaml run --rm migrate
docker compose -f docker/compose.yaml up -d --no-deps web content collab
docker compose -f docker/compose.yaml up -d --no-deps worker scheduler

Rekkefølgen er bevisst:

  1. Migrer først, mens den gamle utgivelsen betjener trafikk. Utvidelsesmigreringer er usynlige for den.
  2. Webnivået deretter. Ved SIGTERM vipper hver webprosess /readyz til draining, fullfører pågående forespørsler innen 30 sekunder, lukker strømmer med et gjenkoblingstips, og avslutter. stop_grace_period er 40 sekunder slik at Compose aldri kutter en sunn tømming.
  3. Arbeiderne sist, slik at den nyeste hendelsesformen produseres før den nyeste forbrukeren forventer den. Arbeidere slutter å hente med én gang og får 120 sekunder; en jobb som ikke kan fullføres hentes igjen et annet sted, noe som er trygt fordi hver jobb er idempotent. Planleggeren overleverer lederskapet ved neste tick.

På én vert erstatter Compose hver container etter tur, så det er et kort gap per tjeneste. For intet gap i det hele tatt, kjør webnivået som to containere bak din egen proxy (en overstyringsfil som legger til en andre webtjeneste uten publisert port), og gjenskap dem én om gangen, og vent til hver melder sunn før den neste.

Flere verter eller en orkestrator

Bruk samme rekkefølge: migrer én gang fra én jobb, rull deretter webnivået med én ekstra og null utilgjengelige, deretter arbeiderne. Pek beredskapssonder mot /readyz og livlighet mot /healthz.

Med dedikerte tenantdatabaser gjør migrate-steget begge: det migrerer kontrolldatabasen først, deretter hver database listet i ops.tenant_database, én om gangen, hver under sin egen lås. En feil i én tenantdatabase stopper ikke de andre. Når alle databaser er ferdige sammenligner det migreringshovedbøkene og avslutter med feil med mindre alle databaser har brukt nøyaktig migreringene kontrolldatabasen har, og navngir hver som ligger bak eller foran. Samme kommando installerer køtabellene i hver database, fordi arbeideren forbruker en festet tenants jobber der de ble skrevet.

bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout

Vanlig migrering og førstegangsoppsett installerer også de kanoniske engelske juridiske dokumentene fra Quire-operatøren i ops.platform_policy_version. Installasjonsprogrammet er idempotent: bare manglende engelske tekster og nøyaktig de plassholdertekstene som migreringen opprettet, erstattes. Frø arkiveres, og en ny publisert versjon settes inn; historiske akseptreferanser og tekster beholdes. Enhver ekte operatørskrevet versjon, også et utkast, bevares og må forvaltes via plattformens policy-konsoll. Leietakerens policydokumenter, versjoner og samtykke endres aldri av denne overgangen. Dette er publisering av operatørtekst, ikke juridisk sertifisering eller automatisk oppfyllelse av dens løfter.

Hver dedikerte database nås gjennom navnet den er registrert under. En database registrert som env:QUIRE_DB_NORTHWIND_URL trenger:

Variabel Brukt til
QUIRE_DB_NORTHWIND_URL Applikasjonsrollen, for webnivået og arbeideren
QUIRE_DB_NORTHWIND_URL_MIGRATOR Migratorrollen, for denne kommandoen og for flyttinger
QUIRE_DB_NORTHWIND_URL_SUPERUSER Valgfri: gjenbruker oppstarten (roller, skjemaer, hjelpere) før migrering

En registrert database uten _MIGRATOR-tilkobling rapporteres som en feil, hoppes aldri over. Webnivået kan rulle når kontrolldatabasen er ferdig. En tenantdatabase som ligger en time bak varsler; et døgn varsler med personsøker.

pgvector

Fra migrering 0264 bruker jordingskorpuset en pgvector HNSW-indeks der tjeneren har utvidelsen; Compose-postgres-tjenesten bygges med den (docker/postgres.Dockerfile). Den første migrate etter bytte av bilder oppretter utvidelsen gjennom superbruker-oppstarten, og 0264 legger deretter til en generert vektorkolonne og bygger indeksen. Å legge til kolonnen skriver app.ai_chunk om én gang under en eksklusiv lås, slik at jordingsforespørsler venter på den; ingenting annet berører den tabellen.

På en tjener uten pgvector logger 0264 et varsel og endrer ingenting, og gjenfinning forblir eksakt. Med en pgvector eldre enn 0.8 bygges kolonnen og indeksen men gjenfinning forblir eksakt til utvidelsen oppgraderes (alter extension vector update), fordi filtrerte HNSW-skanninger trenger 0.8s iterative skanninger. For å aktivere den senere på en tjener uten den, installer utvidelsen, kjør oppstarten igjen (eller create extension vector som superbruker), deretter som quire_migrator:

set maintenance_work_mem = '1GB';  -- the HNSW build is much faster in memory
select ops.ai_chunk_enable_vector_index();

Den er idempotent og returnerer enabled eller unavailable. Kjør den på hver dedikerte tenantdatabase også.

Rulle tilbake

Å rulle tilbake kode er alltid tilgjengelig: sett QUIRE_RELEASE til forrige tag og up -d igjen. Det virker fordi skjemaet er kompatibelt i begge retninger innen en utgivelse.

Å rulle tilbake skjema tilbys ikke. Hva som ikke kan omgjøres, og hvordan man gjenoppretter fra det:

Ikke reversibelt Gjenoppretting
En kontraktsmigrering som fjernet en kolonne Punkt-i-tid-gjenoppretting til før fjerningen inn i en ny database, ekstraher, flett
En dataendring på stedet Det samme, deretter avstem skrivinger siden
Sendte webhooks og hendelser Kompenserende hendelser, aldri sletting
Sendt e-post Et menneske skriver oppfølgingen
Revisjonshashkjeden Skrives aldri om; legg ved en rettelsesoppføring

Derfor leveres en kontraktsmigrering alene: en gjenoppretting har da en ren grense.

Sjekke oppgraderingen

docker compose -f docker/compose.yaml ps           # every service healthy
curl -fsS http://localhost:8080/readyz             # ready, and what is configured
docker compose -f docker/compose.yaml logs migrate # the migrations applied
Navigasjon

Skriv for å søke…

↑↓ naviger↵ velgEsc lukk