বিষয়বস্তুতে যান

Downtime ছাড়া upgrade

নিজে host করা Quire-কে downtime ছাড়া upgrade করুন।

Markdown হিসেবে দেখুন

নিয়মগুলো docs/architecture/23-ops.md-এর section 7 এবং docs/architecture/07-data.md-এর section 4.1-এ আছে। এখানে প্রক্রিয়াটি দেওয়া হলো।

যে নিশ্চয়তা upgrade নিরাপদ করে

Release R schema R এবং schema R minus one—দুটির সঙ্গেই সঠিকভাবে চলে। প্রতিটি schema change-কে expand, transition ও contract-এ ভাগ করা হয়:

  1. Expand: নতুন column, table বা index যোগ করুন। পুরোনো code সেটি উপেক্ষা করে।
  2. Transition, অন্তত একটি release ধরে: নতুন code দুই রকম গঠনেই লেখে ও নতুনটি পড়ে; আবার শুরু করা যায় এমন job পুরোনো row পূরণ করে।
  3. Contract: পরের কোনো release-এ শুধু পুরোনো গঠন বাদ দিন।

তাই rolling upgrade-এর প্রতিটি মুহূর্তে পুরোনো ও নতুন process একই database ভাগ করে ব্যবহার করতে পারে। Down migration নেই: এক ঘণ্টা আগে কোনো column বাদ দিলে ওই ঘণ্টায় লেখা row ফিরিয়ে আনা যাবে না।

প্রতিটি release-এ schema-compat CI job নতুন schema-র বিরুদ্ধে আগের release-এর test চালিয়ে এই নিশ্চয়তা পরীক্ষা করে।

শুরু করার আগে

  1. Release note পড়ুন। Maintenance window লাগবে এমন release-এ সর্বোচ্চ একটি অনুমানসহ তা বলা থাকে।
  2. Restore drill চালান অথবা নিশ্চিত করুন এই release-এর জন্য সফলভাবে চালানো হয়েছে (backup-restore.md)। Drill ব্যর্থ হলে upgrade করা যাবে না।
  3. Base backup নিন: docker compose -f docker/compose.yaml --profile backup run --rm backup।

Docker Compose, একটি 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 scheduler

ক্রমটি ভেবেচিন্তে নির্ধারণ করা হয়েছে:

  1. আগে migrate, পুরোনো release traffic পরিবেশন করার সময়। Expand migration পুরোনো release-এর কাছে অদৃশ্য।
  2. এরপর web tier। SIGTERM পেলে প্রতিটি web process /readyz-এ draining দেখায়, চলমান request সর্বোচ্চ 30 সেকেন্ডে শেষ করে, reconnect hint-সহ stream বন্ধ করে এবং বেরিয়ে যায়। stop_grace_period 40 সেকেন্ড, যাতে সুস্থ drain কখনো Compose কেটে না দেয়।
  3. সবশেষে worker, যাতে নতুনতম consumer তা আশা করার আগেই নতুনতম event shape তৈরি হয়। Worker সঙ্গে সঙ্গে fetch বন্ধ করে এবং 120 সেকেন্ড পায়; কোনো job শেষ করা না গেলে অন্য জায়গায় আবার fetch হয়, যা নিরাপদ কারণ প্রতিটি job idempotent। পরবর্তী tick-এ scheduler নেতৃত্ব হস্তান্তর করে।

এক host-এ Compose একটির পর একটি container বদলায়, তাই প্রতিটি service-এ অল্প সময়ের বিরতি থাকে। একেবারেই বিরতি না চাইলে নিজের proxy-র পেছনে দুটি web container চালান (override file-এ প্রকাশিত port ছাড়া দ্বিতীয় web service যোগ করে), এবং একবারে একটি করে recreate করুন; পরেরটি করার আগে প্রতিটি সুস্থ হয়েছে বলে জানানো পর্যন্ত অপেক্ষা করুন।

একাধিক host বা orchestrator

একই ক্রম ব্যবহার করুন: একটি job থেকে একবার migrate করুন, তারপর surge one ও unavailable zero রেখে web tier roll করুন, তারপর worker। Readiness probe /readyz-এ এবং liveness probe /healthz-এ দিন।

নির্দিষ্ট tenant database থাকলে migrate ধাপে দুটো কাজই হয়: আগে control database migrate হয়, তারপর ops.tenant_database-এ তালিকাভুক্ত প্রতিটি database আলাদা lock-এর অধীনে একবারে একটি করে migrate হয়। একটি tenant database-এ ব্যর্থতা অন্যগুলোকে থামায় না। সব database শেষ হলে migration ledger তুলনা করে; প্রতিটিতে control database-এর ঠিক একই migration না চললে কোনটি পিছিয়ে বা এগিয়ে তা উল্লেখ করে non-zero status-এ শেষ হয়। একই command প্রতিটি database-এ queue table-ও install করে, কারণ worker নির্দিষ্ট tenant-এর job যে database-এ লেখা, সেখান থেকেই নেয়।

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

প্রতিটি নির্দিষ্ট database নিবন্ধনের সময় যে নামে দেওয়া হয়েছে সেটি দিয়ে পৌঁছানো হয়। env:QUIRE_DB_NORTHWIND_URL নামে নিবন্ধিত database-এর জন্য লাগবে:

Variable কী কাজে লাগে
QUIRE_DB_NORTHWIND_URL Application role, web tier ও worker-এর জন্য
QUIRE_DB_NORTHWIND_URL_MIGRATOR Migrator role, এই command ও স্থানান্তরের জন্য
QUIRE_DB_NORTHWIND_URL_SUPERUSER ঐচ্ছিক: migration-এর আগে bootstrap (role, schema, helper) আবার প্রয়োগ করে

_MIGRATOR connection নেই এমন নিবন্ধিত database-কে failure হিসেবে জানানো হয়, কখনো বাদ দেওয়া হয় না। Control database migration শেষ হলেই web tier roll করা যায়। Tenant database এক ঘণ্টা পিছিয়ে থাকলে warning, এক দিন হলে page পাঠানো হয়।

pgvector

Migration 0264 থেকে grounding corpus server-এ extension থাকলে pgvector HNSW index ব্যবহার করে; Compose-এর postgres service-এ এটি থাকে (docker/postgres.Dockerfile)। Image বদলানোর পর প্রথম migrate superuser bootstrap দিয়ে extension তৈরি করে, এরপর 0264 generated vector column যোগ করে ও index তৈরি করে। Column যোগ করতে exclusive lock-এ একবার app.ai_chunk rewrite হয়, তাই grounding request-গুলো অপেক্ষা করে; আর কিছু ওই table-এ হাত দেয় না।

pgvector নেই এমন server-এ 0264 notice log করে, কিন্তু কোনো পরিবর্তন করে না; retrieval exact-ই থাকে। 0.8-এর পুরোনো pgvector-এ column ও index তৈরি হয়, কিন্তু extension upgrade (alter extension vector update) না হওয়া পর্যন্ত retrieval exact থাকে, কারণ filtered HNSW scan-এর জন্য 0.8-এর iterative scan দরকার। পরে extension নেই এমন server-এ এটি চালু করতে extension install করে 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();

এটি idempotent, এবং enabled অথবা unavailable ফেরত দেয়। অন্য dedicated tenant database-গুলোতেও এটি চালান।

Rollback

Code rollback সবসময় করা যায়: QUIRE_RELEASE আগের tag-এ সেট করে আবার up -d চালান। একই release-এর মধ্যে schema দুই দিকেই compatible বলে এটি কাজ করে।

Schema rollback দেওয়া হয় না। যেগুলো ফেরানো যায় না এবং সেগুলো থেকে কীভাবে সেরে উঠবেন:

ফেরানো যায় না পুনরুদ্ধার
Column বাদ দেওয়া contract migration বাদ দেওয়ার আগের সময়ে point-in-time restore করে নতুন database-এ তুলুন, merge করুন
Data-তে সরাসরি পরিবর্তন একইভাবে restore, তারপর পরের write-গুলো মিলিয়ে নিন
পাঠানো webhook ও event Deletion নয়, তার ক্ষতিপূরণমূলক event তৈরি করুন
পাঠানো email একজন মানুষ পরবর্তী বার্তা লিখবেন
Audit hash chain কখনো rewrite নয়; correction entry append করুন

এই কারণেই contract migration একাই release হয়: restore-এ তখন পরিষ্কার সীমা থাকে।

Upgrade পরীক্ষা

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 বন্ধ করুন