لماذا يمكن لأي تغيير صغير في مخطط قاعدة البيانات أن يعطل بيئة الإنتاج

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

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

الفرق الجوهري بين الكود والمخطط

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

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

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

إضافة عمود صغير تسبب مشاكل كبيرة

لنأخذ مثالاً ملموساً. لديك جدول users بعمود email معرف كـ varchar(255). قررت زيادة الحد إلى varchar(500). إنه تغيير في نوع عمود واحد. كم يمكن أن يكون سيئاً؟

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

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

إليك SQL الذي قد يسبب الانقطاع الموصوف أعلاه:

-- خطير: يقفل جدول users بالكامل، ويمنع جميع القراءات والكتابات
ALTER TABLE users ADD COLUMN phone_number VARCHAR(20) NOT NULL;

-- بديل أكثر أماناً: أضف العمود بدون NOT NULL أولاً،
-- ثم قم بالملء الخلفي، ثم أضف القيد مع مهلة للقفل
ALTER TABLE users ADD COLUMN phone_number VARCHAR(20);

-- الملء الخلفي على دفعات (كود التطبيق يعالج القيم المفقودة)
UPDATE users SET phone_number = 'unknown' WHERE phone_number IS NULL;

-- أضف NOT NULL مع مهلة للقفل لتجنب الحظر غير المحدد
SET lock_timeout = '5s';
ALTER TABLE users ALTER COLUMN phone_number SET NOT NULL;

الجملة الأولى تقفل الجدول طوال مدة العملية. على جدول كبير، قد يستغرق هذا دقائق، مما يسبب مهلات متسلسلة عبر جميع مثيلات التطبيق.

تغييرات النوع التي تكسر الاستعلامات بصمت

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

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

حذف الأعمدة غير المستخدمة هو أيضاً محفوف بالمخاطر

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

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

لماذا تغييرات المخطط هي تغييرات جذرية

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

قد يتم الوصول إلى جدول واحد في قاعدة البيانات بواسطة:

  • التطبيق الرئيسي
  • معالجات المهام الخلفية
  • أدوات إعداد التقارير
  • خطوط أنابيب تحليل البيانات
  • الخدمات القديمة
  • الاستعلامات المخصصة من فرق العمليات
  • التكاملات الخارجية

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

المبدأ الأساسي

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

قائمة تحقق عملية قبل أي تغيير في المخطط

قبل تشغيل ترحيل في الإنتاج، تحقق من هذه النقاط:

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

ماذا يعني هذا لعملية النشر الخاصة بك

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

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

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