---
title: "Jaunināšana bez dīkstāves"
description: "Jauniniet pašmitinātu Quire bez dīkstāves."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/lv/llms.txt
> Use this file to discover all available pages before exploring further.

# Jaunināšana bez dīkstāves

<span id="upgrading-without-downtime"></span>

Noteikumi ir `docs/architecture/23-ops.md` 7. sadaļā un
`docs/architecture/07-data.md` 4.1. sadaļā. Šī ir kārtība.

## Garantija, kas to padara drošu <!--quire:the-guarantee-that-makes-it-safe-->

**Versija R darbojas pareizi pret shēmu R un shēmu R mīnus viens.** Katra
shēmas izmaiņa ir sadalīta paplašinājumā, pārejā un sašaurinājumā:

1. **Paplašinājums**: pievieno jaunu kolonnu, tabulu vai indeksu. Vecais kods
   to ignorē.
2. **Pāreja** vismaz vienu versiju: jaunais kods raksta abas formas un lasa
   jauno; atsākams darbs aizpilda vecās rindas.
3. **Sašaurinājums**: izmet veco formu vēlākā versijā, atsevišķi.

Tāpēc katrā plūstoša jauninājuma brīdī vecie un jaunie procesi var dalīties ar
vienu datubāzi. Atgriešanas migrāciju nav: migrācija, kas pirms stundas nometa
kolonnu, nevar atdot rindas, kas tajā stundā tika ierakstītas.

CI darbs `schema-compat` pārbauda garantiju katrai versijai, palaist iepriekšējās
versijas testus pret jauno shēmu.

## Pirms sākat <!--quire:before-you-start-->

1. Izlasiet piezīmes par versiju. Versija, kurai vajadīgs uzturēšanas logs, to
   norāda ar prognozi; ne vairāk kā viena uz versiju.
2. Palaidiet atjaunošanas mācību vai apstipriniet, ka tā šai versijai izdevās
   zaļa ([backup-restore.md](/lv/ops/backup-restore/)). Neizdevusies mācība bloķē
   jaunināšanu.
3. Ņemiet bāzes dublējumu: `docker compose -f docker/compose.yaml --profile backup
   run --rm backup`.

## Docker Compose, viens serveris <!--quire:docker-compose-one-host-->

```sh
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
```

Secība ir apzināta:

1. **Vispirms migrē**, kamēr vecā versija apkalpo trafiku. Paplašinājuma
   migrācijas tai ir neredzamas.
2. **Pēc tam tīmekļa slānis.** Saņemot SIGTERM, katra web procesa `/readyz`
   pārslēdzas uz `draining`, 30 sekunžu laikā pabeidz pārtrauktos pieprasījumus,
   aizver straumes ar atkārtotas savienošanās mājienu un iziet.
   `stop_grace_period` ir 40 sekundes, lai Compose nekad nepārtrauktu veselīgu
   iztukšošanu.
3. **Visbeidzot Workers**, lai jaunākā notikuma forma tiktu izveidota pirms
   jaunākā patērētāja to gaida. Workers uzreiz pārstāj vilkt un saņem 120
   sekundes; darbs, ko nevar pabeigt, tiek atkal vilkts citur, kas ir droši,
   jo katrs darbs ir idempotents. Plānotājs vadību nodod nākamajā tiksē.

Uz viena servera Compose aizvieto katru konteineru pēc kārtas, tāpēc katram
pakalpojumam ir īss pārtraukums. Lai pārtraukuma nebūtu vispār, palaidiet
tīmekļa slāni kā divus konteinerus aiz sava starpniekservera (pārklājuma fails,
kas pievieno otro web pakalpojumu bez publicēta porta) un izveidojiet tos pa
vienam, gaidot, kamēr katrs ziņo par veselību, pirms sākat nākamo.

## Vairāki serveri vai orķestrators <!--quire:several-hosts-or-an-orchestrator-->

Izmantojiet to pašu secību: migrējiet vienreiz no viena darba, pēc tam velciet
tīmekļa slāni ar surge one un unavailable zero, pēc tam darbinīkus. Gatavības
probe norādiet uz `/readyz`, bet dzīvotnes probe — uz `/healthz`.

Ar atsevišķām nomnieku datubāzēm solis `migrate` dara abus: vispirms migrē
kontroldatubāzi, pēc katru datubāzi, kas uzskaitīta `ops.tenant_database`, pa
vienai, katra zem sava slēdzenes. Kļūda vienā nomnieku datubāzē neaptur pārējās.
Kad katra datubāze ir gatava, tā salīdzina migrāciju žurnālus un iziet ar
nenulles kodu, ja vien katra datubāze nav piemērojusi tieši tās pašas migrācijas,
ko kontroldatubāze, nosaucot katru, kas atpaliek vai ir priekšā. Tā pati komanda
katrā datubāzē uzstāda rindu tabulas, jo darbinīks patērē piesaistītā nomnieka
darbus tur, kur tie tika ierakstīti.

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

Katru atsevišķo datubāzi sasniedz caur nosaukumu, zem kura tā ir reģistrēta.
Datubāze, kas reģistrēta kā `env:QUIRE_DB_NORTHWIND_URL`, vajag:

| Mainīgais | Kam tiek izmantots |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Lietojumprogrammas loma tīmekļa slānim un darbinīkam |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Migrētāja loma šai komandai un pārvietojumiem |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Izvēles: atkārto sagatavošanu (lomas, shēmas, palīgfunkcijas) pirms migrēšanas |

Reģistrēta datubāze bez `_MIGRATOR` savienojuma tiek ziņota kā kļūda, nekad
netiek izlaista. Tīmekļa slāni var sākt velt, tiklīdz kontroldatubāze ir gatava.
Nomnieku datubāze, kas stundu atpaliek, brīdina; dienu atpaliekot — izsauc.

## pgvector <!--quire:pgvector-->

No migrācijas 0264 pamatojuma korpuss izmanto pgvector HNSW indeksu, ja
serverī ir paplašinājums; Compose `postgres` pakalpojums ir uzbūvēts ar to
(`docker/postgres.Dockerfile`). Pirmā `migrate` pēc attēlu maiņas izveido
paplašinājumu caur superlietotāja sagatavošanu, un pēc tam 0264 pievieno
ģenerētu vektoru kolonnu un uzbūvē indeksu. Kolonnas pievienošana reizi
pārraksta `app.ai_chunk` zem ekskluzīvas slēdzenes, tāpēc pamatojuma
pieprasījumi to gaida; nekas cits šo tabulu neaiztiec.

Serverī bez pgvector 0264 reģistrē paziņojumu un neko nemaina, un meklēšana
paliek precīza. Ar pgvector, kas vecāks par 0.8, kolonna un indekss tiek
uzbūvēti, bet meklēšana paliek precīza, līdz paplašinājums tiek jaunināts
(`alter extension vector update`), jo filtrētiem HNSW skenējumiem vajag 0.8
iteratīvos skenējumus. Lai to vēlāk ieslēgtu serverī, kurā tā nav, uzstādiet
paplašinājumu, vēlreiz palaidiet sagatavošanu (vai `create extension vector`
kā superlietotājs), pēc tam kā `quire_migrator`:

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

Tā ir idempota un atgriež `enabled` vai `unavailable`. Palaidiet to arī katrā
atsevišķajā nomnieku datubāzē.

## Atgriešana <!--quire:rolling-back-->

Atgriešana ar **kodu** vienmēr ir pieejama: iestatiet `QUIRE_RELEASE` uz
iepriekšējo birku un vēlreiz `up -d`. Tas darbojas, jo shēma versijas robežās
abi virzieni ir saderīga.

Atgriešana ar **shēmu** netiek piedāvāta. Kas nevar tikt atsaukts un kā no tā
atgūties:

| Nav atgriežams | Atgūšanās |
| --- | --- |
| Sašaurinājuma migrācija, kas nometa kolonnu | Atgriešanās punkta laikā pirms nomešanas jaunā datubāzē, izvilkt, apvienot |
| Vietēja datu izmaiņa | Tas pats, pēc tam salīdzināt ierakstījumus kopš tā |
| Nosūtītie tīmekļa āķi un notikumi | Kompensējoši notikumi, nekad dzēšana |
| Nosūtīts e-pasts | Cilvēks uzraksta turpinājumu |
| Audita maiņas ķēde | Nekad nepārrakstīta; pievieno labojuma ierakstu |

Tāpēc sašaurinājuma migrācija nāk atsevišķi: atjaunošanai tad ir tīra robeža.

## Jauninājuma pārbaude <!--quire:checking-the-upgrade-->

```sh
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
```

Source: https://docs.quirelms.com/lv/ops/upgrade/index.mdx
