---
title: "Pag-upgrade nang walang downtime"
description: "Mag-upgrade ng self-hosted na Quire nang walang downtime."
image: "https://docs.quirelms.com/og.png"
---

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

# Pag-upgrade nang walang downtime

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

Nasa `docs/architecture/23-ops.md` seksiyon 7 at `docs/architecture/07-data.md`
seksyon 4.1 ang mga tuntunin. Narito ang pamamaraan.

## Ang garantiyang nagpapaligtas sa upgrade <!--quire:the-guarantee-that-makes-it-safe-->

**Tumatakbo ang release R sa schema R at schema R minus one.** Hinahati ang
bawat pagbabago sa schema sa expand, transition, at contract:

1. **Expand**: idagdag ang bagong column, table, o index. Hindi ito papansinin
   ng lumang code.
2. **Transition**, nang kahit isang release: parehong anyo ang isinusulat ng
   bagong code at bagong anyo ang binabasa; pinupunan ng resumable job ang lumang row.
3. **Contract**: alisin nang mag-isa ang lumang anyo sa susunod na release.

Kaya sa bawat sandali ng rolling upgrade, maaaring magkasalo sa iisang database
ang luma at bagong proseso. Walang down migration: hindi maibabalik ng migration
na nagtanggal ng column isang oras na ang nakalipas ang mga row na naisulat sa
oras na iyon.

Sinusuri ng CI job na `schema-compat` ang garantiya sa bawat release sa
pamamagitan ng pagpapatakbo ng mga test ng nakaraang release laban sa bagong schema.

## Bago magsimula <!--quire:before-you-start-->

1. Basahin ang release note. Sasabihin ng release na nangangailangan ng
   maintenance window kung kailangan ito at gaano katagal; hanggang isa lang kada release.
2. Patakbuhin ang restore drill o tiyaking matagumpay itong tumakbo para sa
   release na ito ([backup-restore.md](/fil/ops/backup-restore/)). Pinipigil ng nabigong
   drill ang upgrade.
3. Kumuha ng base backup: `docker compose -f docker/compose.yaml --profile backup
   run --rm backup`.

## Docker Compose, iisang host <!--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
```

Sadyang ganito ang pagkakasunod-sunod:

1. **Unahin ang migration** habang nagsisilbi pa ng traffic ang lumang release.
   Hindi ito makikita ng lumang code.
2. **Sumunod ang web tier.** Sa SIGTERM, itinatakda ng bawat web process sa
   `/readyz` bilang `draining`, tinatapos sa loob ng 30 segundo ang kasalukuyang
   request, isinasara ang stream na may pahiwatig na kumonektang muli, at
   lumalabas. 40 segundo ang `stop_grace_period` kaya hindi pinuputol ng Compose
   ang maayos na pag-drain.
3. **Huli ang worker**, para malikha ang pinakabagong hugis ng event bago ito
   asahan ng pinakabagong consumer. Hihinto agad ang worker sa pagkuha ng trabaho
   at bibigyan ng 120 segundo; kukunin muli sa ibang lugar ang hindi natapos na
   job. Ligtas ito dahil idempotent ang lahat ng job. Ipinapasa ng scheduler ang
   pamumuno sa susunod na tick.

Sa iisang host, sunod-sunod na pinapalitan ng Compose ang container, kaya may
maikling pagitan sa bawat service. Para tuluyang walang pagitan, patakbuhin ang
web tier bilang dalawang container sa likod ng sarili mong proxy (override file
na may ikalawang web service na walang published port) at isa-isang buuin muli,
hinihintay na maging healthy ang isa bago ang kasunod.

## Maraming host o orchestrator <!--quire:several-hosts-or-an-orchestrator-->

Gamitin ang parehong pagkakasunod: minsanang migrate, i-roll ang web tier na may
surge na isa at unavailable na zero, saka ang worker. Ituro ang readiness probe
sa `/readyz` at liveness sa `/healthz`.

Sa dedicated tenant database, ginagawa ng hakbang na `migrate` ang dalawa:
inuuna ang control database at saka iniisa-isa ang nasa `ops.tenant_database`,
bawat isa sa sariling lock. Hindi pinatitigil ng failure sa isang tenant database
ang iba. Kapag tapos na ang lahat, ikinukumpara ang migration ledger at non-zero
ang exit kung hindi eksaktong kapareho ng control database ang mga migration sa
bawat database; pinapangalanan ang bawat kulang o sobra. Ini-install din ng
command ang queue table sa bawat database dahil doon kinukuha ng worker ang job
ng pinned tenant kung saan ito isinulat.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```
Ang normal na migrasyon at ang unang pag-setup ay nag-i-install din ng mga kanonikal na Ingles na legal na dokumento ng operator ng Quire sa `ops.platform_policy_version`. Idempotent ang installer: ang mga nawawalang Ingles na body at ang eksaktong mga placeholder na body na itinanim ng migrasyon lang ang pinapalitan. Ina-archive ang mga seed at isinisingit ang bagong published na bersyon; nananatili ang mga makasaysayang acceptance reference at mga body. Ang anumang tunay na operator-authored na bersyon, kabilang ang draft, ay napapanatili at dapat pangasiwaan sa pamamagitan ng Policies console ng platform. Ang mga dokumento, bersyon, at consent ng patakaran ng tenant ay hindi kailanman binabago ng cutover na ito. Ito ay paglalathala ng teksto ng operator, hindi legal na sertipikasyon o awtomatikong pagtupad ng mga pangako nito.


Inaabot ang bawat dedicated database sa rehistradong pangalan nito. Kailangan ng
nakarehistrong database na `env:QUIRE_DB_NORTHWIND_URL` ang sumusunod:

| Variable | Gamit |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Application role para sa web tier at worker |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Migrator role para sa command at paglilipat |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Opsyonal: muling naglalapat ng bootstrap (mga role, schema, helper) bago mag-migrate |

Ituturing na failure, at hindi lalaktawan, ang rehistradong database na walang
`_MIGRATOR` connection. Kapag tapos na ang control database, maaari nang i-roll
ang web tier. Babala ang isang oras na atraso ng tenant database; page alert
naman ang isang araw.

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

Mula sa migration 0264, gumagamit ang grounding corpus ng pgvector HNSW index
kapag may extension ang server; binuo rito ang Compose `postgres` service
(`docker/postgres.Dockerfile`). Lumilikha ng extension sa pamamagitan ng
superuser bootstrap ang unang `migrate` matapos magpalit ng image at nagdaragdag
ang 0264 ng generated vector column at index. Muling isinusulat nang minsan ang
`app.ai_chunk` sa ilalim ng exclusive lock kapag idinaragdag ang column, kaya
maghihintay rito ang grounding request; walang ibang table na gagalawin.

Kapag walang pgvector ang server, nagla-log ng notice ang 0264 at walang binabago;
nananatiling exact ang retrieval. Kapag mas luma sa 0.8 ang pgvector, ginagawa
ang column at index ngunit mananatiling exact ang retrieval hanggang i-upgrade ang
extension (`alter extension vector update`), dahil kailangan ng filtered HNSW scan
ang iterative scan ng 0.8. Para i-enable ito kalaunan sa server na wala nito,
i-install ang extension, patakbuhin muli ang bootstrap (o `create extension vector`
bilang superuser), at saka patakbuhin bilang `quire_migrator`:

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

Idempotent ito at ibinabalik ang `enabled` o `unavailable`. Patakbuhin din sa
bawat dedicated tenant database.

## Rollback <!--quire:rolling-back-->

Laging puwedeng i-rollback ang **code**: itakda ang `QUIRE_RELEASE` sa dating
tag at patakbuhin muli ang `up -d`. Gumagana ito dahil magkatugma ang schema sa
magkabilang direksiyon sa loob ng release.

Hindi iniaalok ang pag-rollback sa **schema**. Narito ang hindi mababawi at
paraan ng pagbangon:

| Hindi mababawi | Pagbangon |
| --- | --- |
| Contract migration na nagtanggal ng column | Point-in-time restore sa bagong database bago binura ang column, kunin at i-merge |
| In-place na pagbabago ng data | Gayon din, saka ayusin ang mga isinulat mula noon |
| Naipadalang webhook at event | Mga compensating event, hindi pagbura |
| Naipadalang email | Tao ang susulat ng follow-up |
| Audit hash chain | Hindi ito muling isinusulat; magdagdag ng correction entry |

Kaya mag-isang inilalabas ang contract migration: malinaw ang hangganan ng restore.

## Suriin ang upgrade <!--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/fil/ops/upgrade/index.mdx
