سير عمل ترحيل قاعدة البيانات بدون توقف (نمط التوسيع ثم الانكماش)
سير عمل تنفيذي لتغيير مخطط قاعدة البيانات (Schema Migration) على نظام إنتاج حيّ دون توقف خدمة، مبني كخطوات تشغيل قابلة للتطبيق لا كنص عام. يعتمد نمط التوسيع/الانكماش (Expand/Contract أو Parallel Change): بدل تنفيذ ALTER مباشر يقفل جدولًا كبيرًا ويقطع الكتابة، يضيف البنية الجديدة بالتوازي، ثم يزدوج الكتابة في القديم والجديد، ثم يعبّئ الصفوف القديمة رجعيًا على دفعات، ثم يحوّل القراءة تدريجيًا خلف علم ميزة، وأخيرًا يحذف البنية القديمة بعد نافذة مراقبة. يختلف هذا السير جوهريًا عن سير مراجعة Pull Request وسير تشخيص bug الإنتاج: هدفه تنفيذ تغيير بنيوي على البيانات نفسها بأمان وقابلية تراجع، لا مراجعة كود أو تتبّع عطل. ويغطي أنواع التغيير الخطرة: إعادة تسمية أو تقسيم أو دمج عمود/جدول، تغيير نوع عمود، إضافة قيد NOT NULL أو فهرس فريد على جدول كبير، والتطبيع. يفرض السير عمليات غير حاجزة بحسب المحرك (CREATE INDEX CONCURRENTLY في PostgreSQL، وأدوات الترحيل الحيّة gh-ost أو pt-online-schema-change في MySQL)، وبوابة قرار تمنع تحويل القراءة قبل تطابق البيانات تطابقًا تامًا، وتعبئة رجعية على دفعات بمؤشرات إيقاف عند ارتفاع الكمون أو تأخّر النسخ المتماثل، وخطة تراجع لكل مرحلة عبر إرجاع علم الميزة بدل عكس ترحيل مدمِّر تحت الضغط. مناسب لمهندسي القواعد والمطوّرين وفرق DevOps الذين ينفّذون تغييرات مخطط على أنظمة لا تحتمل التوقف، وقابل للتحويل إلى checklist داخل Claude Code وCursor وCodex.
تقرير ترحيل عربي منظّم: ملخص الخطر، جدول مراحل (المرحلة، الإجراء التقني الدقيق مع أمر SQL أو أداة الترحيل الحيّة، نقطة التحقق، خطوة التراجع)، خطة تعبئة رجعية بحجم دفعة ومؤشرات إيقاف، بوابة قرار للتحقق من تطابق البيانات قبل تحويل القراءة، ثم خطة تراجع لكل مرحلة ومعيار إتمام نهائي — قابل للنسخ ومطبّق دون توقف خدمة.
مثال — تطبيع عمود البريد في جدول users على PostgreSQL (نحو 40 مليون صف، معدل كتابة مرتفع):
ملخص الخطر: تنفيذ ALTER مباشر لإضافة عمود محسوب مع فهرس فريد سيقفل الجدول دقائق ويقطع الكتابة؛ لذا نتبع التوسيع/الانكماش.
جدول المراحل:
| المرحلة | الإجراء التقني | نقطة التحقق | خطوة التراجع |
|---|---|---|---|
| التوسيع | ADD COLUMN email_normalized text (nullable) ثم CREATE INDEX CONCURRENTLY | العمود موجود والفهرس مكتمل بلا قفل | DROP COLUMN/INDEX |
| ازدواج الكتابة | نشر يكتب email و email_normalized=lower(email) خلف علم write_norm | كل صف جديد يملأ الحقلين | إيقاف علم write_norm |
| التعبئة الرجعية | UPDATE على دفعات 10٬000 صف مع مهلة 200ms | نسبة الصفوف الممتلئة ترتفع نحو 100٪ | إيقاف عند replication lag > 30s |
| بوابة القرار | SELECT count(*) WHERE email_normalized IS DISTINCT FROM lower(email) = 0 | تطابق تام | إصلاح الفروق وإعادة التحقق |
| تحويل القراءة | علم read_norm من 5٪ إلى 100٪ | لا أخطاء ولا فرق نتائج | إرجاع read_norm للقديم فورًا |
| المراقبة | 48 ساعة قراءة من الجديد وكتابة مزدوجة | أخطاء صفر | إرجاع العلم |
| الانكماش | نشر يوقف كتابة email القديم | القراءة/الكتابة على الجديد فقط | إعادة الكتابة المزدوجة |
| الحذف | DROP COLUMN email وإزالة الأعلام | البنية نظيفة | استعادة من النسخة الاحتياطية |
خطة التعبئة: دفعات 10٬000 صف، مهلة 200ms، مؤشرات إيقاف: كمون الاستعلام > 500ms أو replication lag > 30s.
معيار الإتمام: email_normalized ممتلئ 100٪ ومطابق، القراءة من الجديد 48 ساعة بلا أخطاء، عمود email محذوف، الأعلام مُزالة، ولم يقع أي توقف. الدَّين المتبقي: حذف دالة الكتابة المزدوجة القديمة من الكود في تنظيف لاحق.