عندما تحتاج ترحيلات قواعد البيانات إلى خط أنابيب خاص بها

لديك خط أنابيب CI/CD متين لتطبيقك. يتم بناء الكود، وتشغيل الاختبارات، وتتم عمليات النشر تلقائيًا. ثم يفتح شخص ما طلب سحب يضيف عمودًا جديدًا إلى جدول المستخدمين. فجأة، يبدو خط الأنابيب النظيف غير مناسب. تشغيل ترحيل قاعدة البيانات في نفس تدفق كود التطبيق يعني إما حظر النشر حتى ينتهي الترحيل، أو تشغيل الترحيل بشكل منفصل والأمل في ألا ينكسر شيء.

المشكلة هي أن تغييرات قاعدة البيانات تتصرف بشكل مختلف عن كود التطبيق. البناء الفاشل يعني فقط عدم وجود نشر جديد. الترحيل الفاشل يمكن أن يفسد البيانات، أو يقفل الجداول، أو يترك قاعدة البيانات في حالة غير متناسقة. أنت بحاجة إلى خط أنابيب مصمم للمخاطر المحددة لتغييرات المخطط، والملء الخلفي للبيانات، والتحقق.

لماذا تقصر خطوط أنابيب التطبيقات

تتبع خطوط أنابيب التطبيقات نمطًا مباشرًا: بناء، اختبار، نشر. إذا فشل اختبار، يتوقف خط الأنابيب. إذا فشل النشر، تقوم بإصلاح المشكلة وإعادة النشر. التراجع عادة ما يكون مجرد نشر الإصدار السابق.

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

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

خط أنابيب منفصل لتغييرات قاعدة البيانات

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

إليك كيفية عمل المراحل بالتسلسل.

يوضح مقتطف YAML التالي كيف يمكنك تعريف هذه المراحل في سير عمل GitHub Actions:

name: Database Migration Pipeline

on:
  pull_request:
    paths:
      - 'migrations/**'

jobs:
  dry-run:
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/dry-run.sh

  migration:
    needs: dry-run
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/migrate.sh

  backfill:
    needs: migration
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/backfill.sh

  reconciliation:
    needs: backfill
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/reconcile.sh

  rollback-test:
    needs: reconciliation
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/rollback.sh
      - run: ./scripts/reconcile.sh

كل وظيفة تعمل فقط إذا نجحت الوظيفة السابقة، مما يعكس تدفق خط الأنابيب الموضح أعلاه.

يظهر مخطط التدفق التالي المراحل الخمس وتقدمها:

flowchart TD A[Dry-Run] --> B[Migration] B --> C[Backfill] C --> D[Reconciliation] D --> E[Rollback Test] E --> F[Manual Approval] F --> G[Production Run] A -- fail --> H[Stop & Notify] B -- fail --> H C -- fail --> H D -- fail --> H E -- fail --> H

المرحلة 1: التجربة الجافة (Dry-Run)

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

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

المرحلة 2: الترحيل (Migration)

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

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

المرحلة 3: الملء الخلفي (Backfill)

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

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

المرحلة 4: المطابقة (Reconciliation)

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

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

المرحلة 5: اختبار التراجع (Rollback Test)

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

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

التشغيل في الإنتاج

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

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

قائمة تحقق عملية لخط أنابيب قاعدة البيانات الخاص بك

  • افصل خط أنابيب قاعدة البيانات عن خط أنابيب التطبيق
  • قم دائمًا بتشغيل تجربة جافة قبل الترحيل الفعلي
  • سجل كل خطوة بطوابع زمنية وأعداد الصفوف
  • قم بتشغيل الملء الخلفي في دفعات صغيرة مع المراقبة
  • أضف فحوصات المطابقة بعد الترحيل والملء الخلفي
  • اختبر سكريبتات التراجع في بيئة الاختبار قبل الإنتاج
  • اطلب موافقة يدوية لعمليات تشغيل الإنتاج
  • احتفظ بالقدرة على إيقاف خط الأنابيب في منتصف المرحلة

الخلاصة

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