رفتن به محتوا

ارتقا بدون از دسترس خارج شدن

Quire خودمیزبان را بدون از دسترس خارج شدن ارتقا دهید.

قاعده‌ها در بخش ۷ از docs/architecture/23-ops.md و بخش 4.1 از docs/architecture/07-data.md آمده‌اند. این صفحه روند اجراست.

تضمینی که ارتقا را ایمن می‌کند

نسخهٔ R با شِمای R و R منهای یک درست کار می‌کند. هر تغییر شِما به سه گام گسترش، گذار و جمع‌کردن تقسیم می‌شود:

  1. گسترش: ستون، جدول یا نمایهٔ تازه را اضافه کنید. کد قدیمی آن را نادیده می‌گیرد.
  2. گذار، دست‌کم برای یک انتشار: کد تازه هر دو شکل را می‌نویسد و شکل جدید را می‌خواند؛ کاری که بتوان از سر گرفت ردیف‌های قدیمی را پر می‌کند.
  3. جمع‌کردن: در انتشاری دیرتر و به‌تنهایی شکل قدیمی را حذف کنید.

پس هنگام هر ارتقای غلتان، فرایندهای قدیمی و جدید می‌توانند از یک پایگاه داده استفاده کنند. بازگردانی migration وجود ندارد: migrationای که ساعتی پیش ستونی را حذف کرده نمی‌تواند ردیف‌هایی را که در آن ساعت نوشته شده‌اند برگرداند.

کار CI با نام schema-compat در هر انتشار این تضمین را می‌سنجد؛ آزمون‌های انتشار پیشین را در برابر شِمای تازه اجرا می‌کند.

پیش از آغاز

  1. یادداشت‌های انتشار را بخوانید. انتشاری که به بازهٔ نگهداری نیاز دارد، زمان تخمینی را می‌گوید؛ در هر انتشار حداکثر یکی.
  2. تمرین بازیابی را اجرا کنید یا مطمئن شوید برای همین انتشار با موفقیت سبز شده است (backup-restore.md). شکست تمرین، ارتقا را متوقف می‌کند.
  3. پشتیبان پایه بگیرید: docker compose -f docker/compose.yaml --profile backup run --rm backup.

Docker Compose، یک میزبان

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

این ترتیب عمدی است:

  1. ابتدا migration، درحالی‌که انتشار قدیمی ترافیک را پاسخ می‌دهد. migrationهای گسترش برای آن نامرئی‌اند.
  2. سپس web tier. هنگام SIGTERM هر فرایند وب، وضعیت /readyz را draining می‌کند، درخواست‌های در جریان را ظرف ۳۰ ثانیه تمام می‌کند، جریان‌ها را با راهنمای اتصال مجدد می‌بندد و خارج می‌شود. stop_grace_period چهل ثانیه است تا Compose هرگز تخلیهٔ سالم را قطع نکند.
  3. در پایان workerها؛ بدین‌ترتیب شکل رویداد تازه پیش از آنکه مصرف‌کنندهٔ تازه انتظارش را داشته باشد تولید می‌شود. workerها فوراً دریافت کار را متوقف می‌کنند و ۱۲۰ ثانیه مهلت دارند؛ کاری که تمام نشود در جای دیگری دوباره دریافت می‌شود و ایمن است، چون هر job تکرارپذیر است. scheduler رهبری را در نوبت بعدی واگذار می‌کند.

در یک میزبان Compose هر container را جداگانه جایگزین می‌کند، پس برای هر سرویس مکث کوتاهی پیش می‌آید. برای بی‌مکث بودن، web tier را پشت proxy خودتان در دو container اجرا کنید (با فایل override سرویس دومی بیفزایید که port منتشر نمی‌کند) و هر کدام را جداگانه بازسازی کنید؛ پیش از بعدی صبر کنید تا وضعیت سالم گزارش شود.

چند میزبان یا orchestrator

همین ترتیب را به کار ببرید: یک‌بار migration را از job یگانه اجرا کنید، سپس web tier را با یک افزایش و صفر مورد خارج از دسترس بچرخانید و پس از آن workerها را. کاوشگرهای آمادگی را به /readyz و کاوشگرهای زنده‌بودن را به /healthz وصل کنید.

در پایگاه‌های دادهٔ tenant اختصاصی، گام migrate هر دو کار را می‌کند: ابتدا پایگاه کنترل را منتقل می‌کند و سپس پایگاه‌های فهرست‌شده در ops.tenant_database را یکی‌یکی و هرکدام زیر قفل خودش می‌گرداند. شکست در پایگاه tenantای دیگران را متوقف نمی‌کند. پس از پایان همه، دفتر migrationها را مقایسه می‌کند و اگر هر پایگاه دقیقاً migrationهای پایگاه کنترل را نداشته باشد با کد خروج غیرصفر پایان می‌یابد و نام هر پایگاه عقب‌مانده یا جلوتر را می‌گوید. همین فرمان جدول‌های صف را هم در هر پایگاه نصب می‌کند، چون worker کارهای tenant سنجاق‌شده را از همان پایگاهی برمی‌دارد که در آن نوشته شده‌اند.

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

مهاجرت معمول و راه‌اندازی اولیه همچنین اسناد حقوقی انگلیسی متعارف اپراتور Quire را در ops.platform_policy_version نصب می‌کنند. نصب‌کننده خودتوان است: فقط متن‌های انگلیسی گمشده و دقیقاً متن‌های موقتی که مهاجرت ایجاد کرده جایگزین می‌شوند. بذرها بایگانی می‌شوند و نسخه منتشرشده جدیدی درج می‌شود؛ ارجاع‌های پذیرش تاریخی و متن‌ها حفظ می‌شوند. هر نسخه اصیل نوشته‌شده توسط اپراتور، از جمله پیش‌نویس، حفظ می‌شود و باید از طریق کنسول سیاست‌های پلتفرم مدیریت شود. اسناد، نسخه‌ها و رضایت سیاست‌های مستأجر هرگز با این گذار تغییر نمی‌کنند. این انتشار متن اپراتور است، نه گواهی حقوقی و نه اجرای خودکار وعده‌های آن.

به هر پایگاه اختصاصی از راه نامی می‌رسند که با آن ثبت شده است. پایگاهی با نام env:QUIRE_DB_NORTHWIND_URL به این‌ها نیاز دارد:

متغیر کاربرد
QUIRE_DB_NORTHWIND_URL نقش برنامه برای web tier و worker
QUIRE_DB_NORTHWIND_URL_MIGRATOR نقش migrator برای این فرمان و جابه‌جایی‌ها
QUIRE_DB_NORTHWIND_URL_SUPERUSER اختیاری: پیش از migration، bootstrap (نقش‌ها، شِماها و helperها) را دوباره اجرا می‌کند

پایگاهی که ثبت شده اما اتصال _MIGRATOR ندارد شکست گزارش می‌شود و هرگز نادیده گرفته نمی‌شود. پس از پایان کار پایگاه کنترل، web tier را می‌توان چرخاند. اگر پایگاه tenant یک ساعت عقب باشد هشدار و یک روز عقب باشد احضار می‌آید.

pgvector

از migration 0264 به بعد، پیکرهٔ grounding از نمایهٔ HNSW در pgvector استفاده می‌کند، اگر سرور افزونه را داشته باشد؛ سرویس postgres در Compose با آن ساخته می‌شود (docker/postgres.Dockerfile). نخستین migrate پس از عوض کردن image، افزونه را از راه superuser bootstrap می‌سازد و 0264 ستون vector تولیدشده را می‌افزاید و نمایه را می‌سازد. افزودن ستون، app.ai_chunk را یک‌بار زیر قفل انحصاری بازنویسی می‌کند، پس درخواست‌های grounding تا پایانش منتظر می‌مانند؛ چیز دیگری به آن جدول دست نمی‌زند.

در سروری که pgvector ندارد، 0264 یادداشت می‌نویسد و چیزی را عوض نمی‌کند؛ بازیابی دقیق باقی می‌ماند. اگر pgvector از 0.8 قدیمی‌تر باشد ستون و نمایه ساخته می‌شوند، اما بازیابی تا ارتقای افزونه (alter extension vector update) دقیق می‌ماند، چون پیمایش‌های HNSW پالایش‌شده به پیمایش تکرارشوندهٔ نسخهٔ 0.8 نیاز دارند. برای فعال کردنش بعداً در سروری که ندارد، افزونه را نصب کنید، bootstrap را دوباره اجرا کنید (یا با superuser create extension vector کنید) و سپس با کاربر quire_migrator:

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

این کار تکرارپذیر است و enabled یا unavailable برمی‌گرداند. در هر پایگاه tenant اختصاصی هم آن را اجرا کنید.

بازگردانی

بازگردانی کد همیشه شدنی است: QUIRE_RELEASE را روی برچسب پیشین بگذارید و دوباره up -d کنید. این کار می‌شود چون شِما در هر دو جهتِ درون یک انتشار سازگار است.

بازگردانی شِما پشتیبانی نمی‌شود. موارد بازنگشتنی و شیوهٔ بازیابی:

بازنگشتنی بازیابی
migration قراردادی که ستونی را حذف کرده بازیابی نقطه‌درزمان به پایگاه تازه‌ای پیش از حذف، استخراج و ادغام
تغییر درجا در داده همان کار و سپس تطبیق نوشته‌های پس از آن
وب‌هوک‌ها و رویدادهای فرستاده‌شده رویدادهای جبرانی، هرگز حذف نه
ایمیل فرستاده‌شده انسانی پیام پیگیری می‌نویسد
زنجیرهٔ hash حسابرسی هرگز بازنویسی نمی‌شود؛ ورودی اصلاحی افزوده می‌شود

به همین دلیل migration قراردادی به‌تنهایی منتشر می‌شود: بازیابی مرز روشنی دارد.

بررسی ارتقا

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
پیمایش

برای جست‌وجو بنویسید…

↑↓ پیمایش↵ انتخابEsc بستن