---
title: "Meningkatkan versi tanpa waktu henti"
description: "Tingkatkan Quire yang dihosting sendiri tanpa waktu henti."
image: "https://docs.quirelms.com/og.png"
---

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

# Meningkatkan versi tanpa waktu henti

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

Aturannya ada di `docs/architecture/23-ops.md` bagian 7 dan `docs/architecture/07-data.md` bagian 4.1. Inilah prosedurnya.

## Jaminan yang membuatnya aman <!--quire:the-guarantee-that-makes-it-safe-->

**Rilis R berjalan dengan benar terhadap skema R dan skema R dikurangi satu.** Setiap perubahan skema dibagi menjadi perluasan, transisi, dan kontraksi:

1. **Perluasan**: tambahkan kolom, tabel, atau indeks baru. Kode lama mengabaikannya.
2. **Transisi**, setidaknya selama satu rilis: kode baru menulis kedua bentuk dan membaca bentuk baru; tugas yang dapat dilanjutkan mengisi baris lama.
3. **Kontraksi**: hapus bentuk lama pada rilis berikutnya, tersendiri.

Dengan demikian, di setiap tahap peningkatan bertahap, proses lama dan baru dapat berbagi satu basis data. Tidak ada migration turun: migration yang menghapus kolom sejam lalu tidak dapat mengembalikan baris yang ditulis selama satu jam itu.

Tugas CI `schema-compat` memeriksa jaminan ini pada setiap rilis dengan menjalankan pengujian rilis sebelumnya terhadap skema baru.

## Sebelum memulai <!--quire:before-you-start-->

1. Baca catatan rilis. Rilis yang memerlukan jendela pemeliharaan akan menyatakannya beserta perkiraan waktu; paling banyak satu per rilis.
2. Jalankan uji pemulihan atau pastikan hasilnya berhasil untuk rilis ini ([backup-restore.md](/id/ops/backup-restore/)). Uji yang gagal menghalangi peningkatan.
3. Ambil cadangan dasar: `docker compose -f docker/compose.yaml --profile backup run --rm backup`.

## Docker Compose pada satu 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
```

Urutan ini disengaja:

1. **Jalankan migration terlebih dahulu**, saat rilis lama masih melayani trafik. Migration perluasan tidak terlihat olehnya.
2. **Berikutnya web tier.** Saat SIGTERM, setiap proses web mengubah `/readyz` menjadi `draining`, menyelesaikan permintaan aktif dalam 30 detik, menutup stream dengan petunjuk untuk menyambungkan ulang, lalu keluar. `stop_grace_period` memberi waktu 40 detik agar Compose tidak memotong proses pengurasan yang sehat.
3. **Terakhir worker**, agar bentuk peristiwa terbaru dihasilkan sebelum consumer terbaru mengharapkannya. Worker langsung berhenti mengambil tugas dan mendapat waktu 120 detik; tugas yang belum selesai diambil lagi oleh worker lain, aman karena setiap tugas idempoten. Scheduler menyerahkan kepemimpinan pada tick berikutnya.

Pada satu host, Compose mengganti container satu per satu sehingga tiap layanan mengalami jeda singkat. Agar tidak ada jeda sama sekali, jalankan dua container web tier di belakang proxy Anda (berkas override menambahkan layanan web kedua tanpa port publik), lalu buat ulang satu per satu dan tunggu masing-masing melaporkan status sehat sebelum melanjutkan.

## Beberapa host atau orchestrator <!--quire:several-hosts-or-an-orchestrator-->

Gunakan urutan yang sama: jalankan migration sekali dari satu tugas, lalu gulir web tier dengan surge satu dan unavailable nol, lalu worker. Arahkan readiness probe ke `/readyz` dan liveness probe ke `/healthz`.

Dengan basis data tenant khusus, langkah `migrate` melakukan dua hal: migrasi basis data kontrol terlebih dahulu, lalu setiap basis data dalam `ops.tenant_database`, satu per satu di bawah lock masing-masing. Kegagalan di satu basis data tenant tidak menghentikan yang lain. Setelah semua selesai, langkah ini membandingkan ledger migration dan keluar dengan status nonzero kecuali setiap basis data telah menerapkan migration yang persis sama dengan basis data kontrol; basis data yang tertinggal atau lebih maju disebutkan. Perintah yang sama memasang tabel antrean di setiap basis data karena worker mengambil tugas tenant yang dipatok di tempat tugas itu ditulis.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```
Migrasi normal dan penyiapan pertama juga menginstal dokumen hukum Inggris kanonis operator Quire ke `ops.platform_policy_version`. Penginstal bersifat idempoten: hanya bodi Inggris yang hilang dan tepat bodi placeholder yang dibuat migrasi yang diganti. Seed diarsipkan dan versi terbitan baru disisipkan; referensi penerimaan historis dan bodi dipertahankan. Setiap versi asli yang ditulis operator, termasuk draf, dilestarikan dan harus dikelola melalui konsol Kebijakan platform. Dokumen, versi, dan persetujuan kebijakan tenant tidak pernah diubah oleh cutover ini. Ini adalah publikasi teks operator, bukan sertifikasi hukum atau pemenuhan otomatis atas janji-janjinya.


Setiap basis data khusus dijangkau melalui nama pendaftarannya. Basis data yang didaftarkan sebagai `env:QUIRE_DB_NORTHWIND_URL` memerlukan:

| Variabel | Digunakan untuk |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Peran aplikasi untuk web tier dan worker |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Peran migrator untuk perintah ini dan pemindahan |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Opsional: menerapkan ulang bootstrap (peran, skema, helper) sebelum migrasi |

Basis data terdaftar tanpa koneksi `_MIGRATOR` dilaporkan gagal, bukan dilewati. Web tier dapat digulirkan setelah basis data kontrol selesai. Keterlambatan basis data tenant satu jam memicu peringatan; keterlambatan satu hari memicu halaman.

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

Mulai migration 0264, korpus grounding menggunakan indeks HNSW pgvector jika server memiliki ekstensi tersebut; layanan Compose `postgres` dibangun dengannya (`docker/postgres.Dockerfile`). `migrate` pertama setelah image diganti membuat ekstensi melalui bootstrap superuser, lalu 0264 menambahkan kolom vector yang dihasilkan dan membangun indeks. Penambahan kolom menulis ulang `app.ai_chunk` sekali di bawah exclusive lock sehingga permintaan grounding menunggu; tidak ada proses lain yang menyentuh tabel tersebut.

Pada server tanpa pgvector, 0264 mencatat pemberitahuan tanpa mengubah apa pun dan pengambilan tetap eksak. Dengan pgvector yang lebih lama dari 0.8, kolom dan indeks tetap dibuat tetapi pengambilan tetap eksak sampai ekstensi ditingkatkan (`alter extension vector update`), karena pemindaian HNSW terfilter membutuhkan pemindaian iteratif versi 0.8. Untuk mengaktifkannya nanti pada server yang belum memilikinya, instal ekstensi, jalankan bootstrap lagi (atau `create extension vector` sebagai superuser), lalu sebagai `quire_migrator`:

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

Perintah ini idempoten dan mengembalikan `enabled` atau `unavailable`. Jalankan juga pada setiap basis data tenant khusus.

## Melakukan rollback <!--quire:rolling-back-->

Rollback **kode** selalu dapat dilakukan: tetapkan `QUIRE_RELEASE` ke tag sebelumnya lalu jalankan `up -d` lagi. Ini berfungsi karena skema kompatibel untuk kedua arah dalam satu rilis.

Rollback **skema** tidak disediakan. Berikut hal yang tidak dapat dibatalkan dan cara memulihkannya:

| Tidak dapat dibalik | Pemulihan |
| --- | --- |
| Migration kontraksi yang menghapus kolom | Pulihkan ke titik waktu sebelum penghapusan di basis data baru, ekstrak, lalu gabungkan |
| Perubahan data langsung di tempat | Lakukan hal yang sama, lalu selaraskan penulisan sejak itu |
| Webhook dan peristiwa yang telah dikirim | Kirim peristiwa kompensasi, jangan hapus |
| Email yang telah dikirim | Tindak lanjut ditulis oleh manusia |
| Rantai hash audit | Tidak pernah ditulis ulang; tambahkan entri koreksi |

Itulah sebabnya migration kontraksi dikirim tersendiri: pemulihan memiliki batas yang jelas.

## Memeriksa peningkatan <!--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/id/ops/upgrade/index.mdx
