لماذا تحتاج قاعدة البيانات إلى خط أنابيب CI/CD خاص بها

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

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

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

عديم الحالة مقابل ذو حالة: الفرق الأساسي

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

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

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

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

مشكلة التوقيت

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

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

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

التوافق ليس اختياريًا

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

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

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

لماذا خطوط الأنابيب المنفصلة

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

يوضح مخطط التدفق التالي كيف يتباعد خطا الأنابيب في التعقيد وفحوصات الأمان:

flowchart TD subgraph App[Application Pipeline] A1[Code commit] --> A2[Build] A2 --> A3[Unit tests] A3 --> A4[Deploy to staging] A4 --> A5[Integration tests] A5 --> A6[Deploy to production] A6 --> A7[Monitor] end subgraph DB[Database Pipeline] B1[Migration script commit] --> B2[Syntax validation] B2 --> B3[Dry-run on staging] B3 --> B4[Schema diff check] B4 --> B5[Performance impact analysis] B5 --> B6[Run migration on staging] B6 --> B7[Verify] B7 --> B8[Run migration on production] B8 --> B9[Verify] end

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

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

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

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

كيف يبدو خط أنابيب قاعدة البيانات الجيد

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

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

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

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

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

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

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

قبل إعداد خط أنابيب قاعدة البيانات الخاص بك، تأكد من أنه يمكنك الإجابة على هذه الأسئلة:

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

الخلاصة

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