لماذا لا يمكنك حذف عمود قاعدة البيانات فحسب

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

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

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

النسخ القديمة لا تزال قيد التشغيل

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

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

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

ترحيل البيانات نادرًا ما يكون فوريًا

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

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

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

التبعيات الخفية في كل مكان

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

ضع في اعتبارك هذه السيناريوهات:

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

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

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

التغييرات غير القابلة للعكس تضخم المخاطر

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

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

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

النهج الأكثر أمانًا: التوسع ثم الانكماش

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

يوضح المخطط الانسيابي أدناه المسارين.

flowchart TD A["هل تريد حذف العمود?"] --> B{"هل توجد نسخ قديمة قيد التشغيل؟"} B -->|نعم| C["استخدم التوسع والانكماش"] B -->|لا| D{"هل توجد تبعيات خفية؟"} D -->|نعم| C D -->|لا| E["حذف فوري"] E --> F["المخاطر: أخطاء، فقدان بيانات، استحالة التراجع"] C --> G["أضف عمودًا جديدًا"] G --> H["املأ البيانات بأثر رجعي"] H --> I["اكتب على كلا العمودين"] I --> J["حول القراءات إلى العمود الجديد"] J --> K["راقب بحثًا عن مشكلات"] K --> L["احذف العمود القديم"]

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

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

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

يقارن مقتطف SQL التالي بين الحذف الفوري المحفوف بالمخاطر والعملية متعددة الخطوات الأكثر أمانًا.

-- غير آمن: حذف العمود فورًا
ALTER TABLE users DROP COLUMN old_plan;

-- أكثر أمانًا: نهج التوسع والانكماش

-- الخطوة 1: أضف العمود الجديد
ALTER TABLE users ADD COLUMN new_plan VARCHAR(50);

-- الخطوة 2: املأ البيانات من العمود القديم إلى الجديد
UPDATE users SET new_plan = old_plan WHERE new_plan IS NULL;

-- الخطوة 3: قم بتحديث التطبيق للكتابة على كلا العمودين
-- (يتم التعامل معها في الكود، وليس SQL)

-- الخطوة 4: بعد التأكد من عدم وجود قراءات على العمود القديم، احذفه
ALTER TABLE users DROP COLUMN old_plan;

قائمة تحقق عملية قبل حذف المخطط

قبل حذف أي عمود أو جدول، تحقق من هذه الشروط:

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

إذا لم يتم استيفاء أي من هذه الشروط، فأنت لست مستعدًا للحذف.

الخلاصة

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