Les regles es descriuen a docs/architecture/23-ops.md, secció 7, i a
docs/architecture/07-data.md, secció 4.1. Aquest és el procediment.
La garantia que ho fa segur
La versió R s’executa correctament tant amb l’esquema R com amb l’esquema R menys un. Cada canvi d’esquema es divideix en fases d’ampliació, transició i retirada:
- Ampliació: afegiu la nova columna, taula o índex. El codi antic no en fa cas.
- Transició, durant almenys una versió: el codi nou escriu totes dues estructures i llegeix la nova; una tasca que es pot reprendre omple les files antigues.
- Retirada: suprimiu l’estructura antiga, tota sola, en una versió posterior.
Així, en qualsevol moment d’una actualització progressiva, els processos antics i nous poden compartir una base de dades. No hi ha migracions descendents: una migració que va suprimir una columna fa una hora no pot recuperar les files que s’hi han escrit durant aquesta hora.
La tasca CI schema-compat comprova aquesta garantia a cada versió i executa
les proves de la versió anterior amb el nou esquema.
Abans de començar
- Llegiu les notes de la versió. Si cal una finestra de manteniment, s’hi indica amb una estimació; com a màxim n’hi ha una per versió.
- Executeu la prova de restauració o comproveu que hagi acabat correctament per a aquesta versió (backup-restore.md). Si falla, no es pot actualitzar.
- Feu una còpia de seguretat base:
docker compose -f docker/compose.yaml --profile backup run --rm backup.
Docker Compose en un sol host
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 schedulerL’ordre és intencionat:
- Primer, les migracions, mentre la versió antiga continua atenent peticions. Aquesta versió no veu les migracions d’ampliació.
- Després, la capa web. En rebre SIGTERM, cada procés web marca
/readyzcom adraining, acaba les peticions en curs en un màxim de 30 segons, tanca les connexions obertes amb una indicació perquè es reconnectin i surt.stop_grace_periodés de 40 segons perquè Compose no interrompi mai una aturada correcta. - Finalment, els workers, perquè es generi primer el format més nou de l’esdeveniment i després el rebi el consumidor més recent. Deixen de recuperar tasques immediatament i disposen de 120 segons; si no en poden acabar una, es recupera en un altre procés, cosa segura perquè totes les tasques són idempotents. A la següent execució, l’scheduler cedeix el lideratge.
En un sol host, Compose substitueix els contenidors un rere l’altre, de manera que hi ha una petita interrupció per servei. Per eliminar-la, executeu dues instàncies de la capa web darrere del vostre proxy amb un fitxer de configuració alternativa que afegeixi un segon servei web sense un port publicat. Recreeu-les una per una i espereu que cadascuna informi que està sana abans de continuar.
Diversos hosts o un orquestrador
Seguiu el mateix ordre: executeu la migració una sola vegada des d’un únic
treball, actualitzeu la capa web amb una instància addicional i cap
d’indisponible, i després els workers. Apunteu les proves de disponibilitat a
/readyz i les proves d’activitat a /healthz.
Amb bases de dades de tenants dedicades, el pas de migrate les migra totes:
primer la base de dades de control i, després, cadascuna de les bases
registrades a ops.tenant_database, d’una en una i amb el seu propi bloqueig.
Si falla una base de dades de tenant, les altres continuen migrant. Quan s’han
completat totes, es comparen els registres de migració; el procés surt amb un
codi diferent de zero si alguna base de dades no ha aplicat exactament les
mateixes migracions que la de control i n’indica quina va avançada o endarrerida.
La mateixa ordre instal·la les taules de cua a cada base, perquè el worker
consumeix a cada base les tasques del tenant corresponent.
bun apps/worker/src/migrate.ts # what the Compose step runs
bun run db:migrate:all # the same, from a checkoutLa migració normal i la configuració inicial també instal·len els documents legals canònics en anglès de l’operador Quire a ops.platform_policy_version. L’instal·lador és idempotent: només se substitueixen els textos en anglès que falten i exactament els textos de reserva que la migració ha sembrat. Les llavors s’arxiven i s’insereix una versió publicada nova; es conserven les referències d’acceptació històriques i els textos. Qualsevol versió escrita realment per l’operador, inclòs un esborrany, es conserva i s’ha de gestionar des de la consola de Polítiques de la plataforma. Els documents, les versions i el consentiment de les polítiques de l’inquilí mai no canvien amb aquesta transició. Això és publicació de text de l’operador, no certificació legal ni compliment automàtic de les seves promeses.
S’accedeix a cada base dedicada pel nom amb què està registrada. Una base
registrada com env:QUIRE_DB_NORTHWIND_URL necessita:
| Variable | Per a què s’utilitza |
|---|---|
QUIRE_DB_NORTHWIND_URL |
Rol d’aplicació, per a la capa web i el worker |
QUIRE_DB_NORTHWIND_URL_MIGRATOR |
Rol de migració, per a aquesta ordre i per als trasllats |
QUIRE_DB_NORTHWIND_URL_SUPERUSER |
Opcional: torna a aplicar la inicialització (rols, esquemes i ajudes) abans de migrar |
Si a una base de dades registrada li manca la connexió _MIGRATOR, es
notifica com a error i no se salta mai. La capa web es pot actualitzar quan
s’hagi completat la base de dades de control. Si una base de tenant porta una
hora de retard, es mostra un avís; si en porta un dia, s’envia una alerta.
pgvector
A partir de la migració 0264, el corpus de context utilitza un índex HNSW de
pgvector quan el servidor té l’extensió instal·lada; el servei postgres de
Compose es compila amb aquesta extensió (docker/postgres.Dockerfile). La
primera migració migrate després de canviar les imatges crea l’extensió
mitjançant la inicialització de superusuari; després, la migració 0264 afegeix
una columna vectorial generada i crea l’índex. Afegir la columna reescriu
app.ai_chunk una vegada amb un bloqueig exclusiu, de manera que les
peticions de context s’hi esperen; cap altra operació modifica aquesta taula.
En un servidor sense pgvector, la migració 0264 registra un avís i no fa cap
canvi; la recuperació continua sent exacta. Si la versió de pgvector és
anterior a 0.8, es creen la columna i l’índex, però la recuperació continua
sent exacta fins que actualitzeu l’extensió (alter extension vector update),
perquè les cerques HNSW filtrades necessiten les cerques iteratives de la
versió 0.8. Per activar-la més endavant en un servidor que no en disposi,
instal·leu l’extensió, torneu a executar la inicialització (o executeu
create extension vector com a superusuari) i, com a quire_migrator:
set maintenance_work_mem = '1GB'; -- the HNSW build is much faster in memory
select ops.ai_chunk_enable_vector_index();És idempotent i retorna enabled o unavailable. Executeu-la també a cada
base de dades tenant dedicada.
Reversions
Sempre és possible revertir el codi: establiu QUIRE_RELEASE a l’etiqueta
anterior i torneu a executar up -d. Funciona perquè dins d’una mateixa
versió l’esquema és compatible en totes dues direccions.
No s’ofereix la reversió de l’esquema. Aquestes accions no es poden desfer; així es recuperen:
| Acció irreversible | Recuperació |
|---|---|
| Una migració de retirada que suprimeix una columna | Restaureu a un moment anterior a la supressió en una base nova; extraieu-ne i fusioneu-ne les dades |
| Un canvi de dades al mateix lloc | El mateix procés i, després, concilieu les escriptures posteriors |
| Webhooks i esdeveniments enviats | Emeteu esdeveniments compensatoris; no els suprimiu mai |
| Correu electrònic enviat | Una persona envia el missatge de seguiment |
| Cadena hash d’auditoria | No es reescriu mai; afegiu-hi una entrada de correcció |
Per això una migració de retirada s’envia tota sola: una restauració té així un punt de separació clar.
Comprovar l’actualització
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