انتقل إلى المحتوى

الترقية دون توقف

رقِّ Quire المستضاف ذاتيًا دون توقف الخدمة.

عرض بتنسيق Markdown

ترد القواعد في docs/architecture/23-ops.md القسم 7 وdocs/architecture/07-data.md القسم 4.1. وهذه هي الإجراءات.

الضمان الذي يجعلها آمنة

يعمل الإصدار R بصورة صحيحة مع المخطط R والمخطط R ناقص إصدار واحد. يُقسم كل تغيير للمخطط إلى توسعة وانتقال وإزالة:

  1. التوسعة: أضف العمود أو الجدول أو الفهرس الجديد. تتجاهله الشيفرة القديمة.
  2. الانتقال: يمتد إصدار واحد على الأقل؛ تكتب الشيفرة الجديدة الشكلين وتقرأ الجديد، وتملأ مهمة قابلة للاستئناف الصفوف القديمة.
  3. الإزالة: احذف الشكل القديم في إصدار لاحق منفرد.

وهكذا يمكن للعمليات القديمة والجديدة مشاركة قاعدة بيانات واحدة في كل لحظة أثناء الترقية التدريجية. ولا توجد عمليات ترحيل عكسية: فعملية الترحيل التي حذفت عمودًا قبل ساعة لا تستطيع استعادة الصفوف التي كُتبت في تلك الساعة.

يتحقق اختبار 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. نفذ الترحيل أولًا بينما يخدم الإصدار القديم حركة المرور. لا تظهر توسعات الترحيل له.
  2. حدّث طبقة الويب بعدها. عند SIGTERM يغير كل عامل ويب /readyz إلى draining، وينهي الطلبات الجارية خلال 30 ثانية، ويغلق التدفقات مع تلميح لإعادة الاتصال، ثم يتوقف. تبلغ قيمة stop_grace_period 40 ثانية، لذا لا يقطع Compose عملية تصريف سليمة.
  3. حدّث العمال أخيرًا كي يُنتج شكل الحدث الأحدث قبل توقع المستهلك الأحدث له. ويتوقف العمال عن جلب المهام فورًا وتُمنح 120 ثانية؛ وأي مهمة لا تكتمل يعاد جلبها في مكان آخر، وهذا آمن لأن كل المهام قابلة لإعادة التنفيذ دون تكرار الأثر. ويسلم المجدول القيادة في النبضة التالية.

على مضيف واحد، يستبدل Compose كل حاوية بالتتابع، فيحدث انقطاع قصير لكل خدمة. ولتفادي أي انقطاع، شغّل خادمي ويب خلف وكيلك مع ملف تجاوز يضيف خدمة ويب ثانية بلا منفذ منشور، وأعد إنشاءهما واحدًا تلو الآخر، وانتظر حتى تظهر صحة كل منهما قبل متابعة الأخرى.

عدة مضيفين أو منسّق

اتبع الترتيب نفسه: نفذ الترحيل مرة واحدة ضمن مهمة واحدة، ثم حدّث طبقة الويب مع surge بمقدار واحد وunavailable بصفر، ثم العمال. وجه فحوص الجاهزية إلى /readyz وفحوص الحيوية إلى /healthz.

مع قواعد بيانات مستأجرين مخصصة، تنفذ خطوة migrate الأمرين: ترحّل قاعدة التحكم أولًا ثم كل قاعدة مدرجة في ops.tenant_database واحدةً تلو الأخرى تحت قفلها الخاص. لا يمنع فشل قاعدة لمستأجر ترحيل البقية. وعند انتهاء جميع القواعد، يقارن الأمر سجلات الترحيل ويخرج برمز غير صفري ما لم تطبق كل قاعدة الترحيلات نفسها التي طبقتها قاعدة التحكم، مع تسمية كل قاعدة متأخرة أو متقدمة. ويثبت الأمر نفسه جداول قائمة الانتظار في كل قاعدة، لأن العامل يستهلك مهام المستأجر المثبت من القاعدة التي كُتبت فيها.

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

يُتصل بكل قاعدة مخصصة عبر الاسم المسجلة به. وتحتاج قاعدة مسجلة باسم env:QUIRE_DB_NORTHWIND_URL إلى ما يلي:

المتغير استخدامه
QUIRE_DB_NORTHWIND_URL دور التطبيق لطبقة الويب والعامل
QUIRE_DB_NORTHWIND_URL_MIGRATOR دور الترحيل لهذا الأمر ولعمليات النقل
QUIRE_DB_NORTHWIND_URL_SUPERUSER اختياري: يعيد تطبيق الإعداد الأساسي (الأدوار والمخططات والمساعدات) قبل الترحيل

تُسجل القاعدة المسجلة التي لا تملك اتصال _MIGRATOR كإخفاق ولا يجري تخطيها. ويمكن تحديث طبقة الويب بعد انتهاء قاعدة التحكم. وإذا تأخرت قاعدة مستأجر ساعة يظهر تحذير، وبعد يوم يرسل تنبيه عاجل.

pgvector

ابتداء من الترحيل 0264 يستخدم مستودع مواد الإسناد فهرس HNSW من pgvector عندما يتوفر الامتداد على الخادم؛ وخدمة Compose المسماة postgres مبنية معه (docker/postgres.Dockerfile). ينشئ أول تشغيل لـmigrate بعد تبديل الصور الامتداد عبر إعداد المستخدم الفائق، ثم يضيف 0264 عمود متجه مولدًا ويبني الفهرس. يعيد العمود كتابة app.ai_chunk مرة واحدة تحت قفل حصري، لذلك تنتظر طلبات الإسناد اكتمالها، ولا يلمس الجدول أي شيء آخر.

إذا لم يتوفر pgvector على الخادم، يسجل 0264 إشعارًا ولا يغير شيئًا، ويبقى الاسترجاع دقيقًا. ومع إصدار pgvector أقدم من 0.8، يُبنى العمود والفهرس لكن يظل الاسترجاع دقيقًا إلى أن يُرقى الامتداد (alter extension vector update)، لأن عمليات HNSW المصفاة تتطلب المسوح التكرارية في 0.8. لتفعيله لاحقًا على خادم لا يتضمنه، ثبّت الامتداد وأعد تشغيل الإعداد الأساسي (أو نفذ 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. نفذها أيضًا في كل قاعدة بيانات مخصصة لمستأجر.

التراجع

التراجع عن الشيفرة متاح دائمًا: عيّن QUIRE_RELEASE إلى الوسم السابق وشغّل up -d مجددًا. ينجح ذلك لأن المخطط متوافق في الاتجاهين ضمن الإصدار.

لا يتوفر التراجع عن المخطط. وما لا يمكن عكسه وطريقة استعادته:

ما لا يمكن عكسه الاستعادة
ترحيل إزالة حذف عمودًا استعد نقطة زمنية قبل الحذف إلى قاعدة جديدة، ثم استخرج البيانات وادمجها
تغيير بيانات في موضعها الطريقة نفسها، ثم التوفيق مع الكتابات اللاحقة
خطافات الويب والأحداث المرسلة أنشئ أحداثًا تعويضية، ولا تحذف
البريد المرسل يتولى شخص كتابة رسالة متابعة
سلسلة تجزئة التدقيق لا يُعاد تحريرها أبدًا؛ أضف إدخال تصحيح

لذلك يُنشر ترحيل الإزالة منفردًا: فالاستعادة عندئذ لها حد واضح.

التحقق من الترقية

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 للإغلاق