لماذا تختلف عمليات نشر قواعد البيانات: شبكة التبعيات الخفية

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

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

ماذا حدث؟ لقد غيرت جدولًا واحدًا، وانكسر كل شيء.

قاعدة البيانات لديها مستهلكون أكثر مما تعتقد

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

إليك ما قد تخدمه قاعدة بيانات إنتاجية نموذجية:

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

flowchart TD DB[قاعدة البيانات الإنتاجية] DB -->|قراءة/كتابة| Web[تطبيق الويب الرئيسي] DB -->|قراءة/كتابة| API[خدمات API الداخلية] DB -->|كتابة| Batch[مهام الدفعة الليلية] DB -->|قراءة| Report[سكريبتات التقارير الأسبوعية] DB -->|قراءة| AdHoc[استعلامات مخصصة - فريق البيانات] DB -->|قراءة/كتابة| Legacy[الخدمات القديمة]
  • تطبيق الويب الرئيسي الذي يستخدمه العملاء
  • خدمات API الداخلية التي تحتفظ بها فرق أخرى
  • مهام الدفعة الليلية التي تعالج آلاف الصفوف
  • سكريبتات التقارير الأسبوعية التي تغذي لوحات المعلومات
  • الاستعلامات المخصصة التي يديرها فريق البيانات أو محللو الأعمال
  • الخدمات القديمة التي لا أحد يريد لمسها ولكنها لا تزال تعمل

كل من هؤلاء المستهلكين يصل إلى قاعدة البيانات بشكل مختلف. قد يقرأ تطبيق الويب عمود status لعرض صفحة. قد تكتب مهمة الدفعة آلاف الصفوف باستخدام INSERT ... SELECT *. قد يعتمد سكريبت التقارير على عرض معين يربط جداول متعددة. قد يكون لدى المحلل استعلام محفوظ يتوقع أعمدة بترتيب معين.

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

المشكلة الحقيقية: أنت لا تعرف من يعتمد على قاعدة البيانات هذه

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

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

لا يمكنك تغيير ما لا تفهمه تمامًا بأمان.

لماذا التوافق العكسي مهم

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

إليك أنماط عملية تقلل المخاطر:

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

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

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

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

المستهلك المنسي: البشر

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

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

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

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

لماذا لا تشبه استرجاعات قاعدة البيانات استرجاعات التطبيقات

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

تغييرات قاعدة البيانات لا تعمل بهذه الطريقة.

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

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

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

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

قبل تشغيل جملة ALTER TABLE في الإنتاج، اذهب من خلال هذه القائمة:

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

الخلاصة

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