هجرات الإوز من أجل تغييرات سلسة في قاعدة البيانات

مرحبًا، صديقي!

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

إليك جدول أعمالنا:

  1. ما هي المشكلة؟
  2. كيف يمكننا إصلاحها؟
  3. مثال بسيط
  4. مثال أكثر تعقيدًا
  5. توصيات
  6. نتائج
  7. استنتاج

ما هي المشكلة؟

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

التحدي الرئيسي

عندما نقوم بإجراء تغييرات “مخطط لها” و”سلسة” على قاعدة البيانات، نحتاج إلى الحفاظ على توافر الخدمة وتلبية متطلبات SLA (حتى لا يعاني المستخدمون من انقطاع الخدمة أو التأخير). تخيل أنك تريد تغيير نوع عمود في جدول يحتوي على 5 ملايين مستخدم. إذا قمت بذلك “بشكل مباشر” (على سبيل المثال، تشغيل ALTER TABLE ببساطة دون إعداد)، قد يتم قفل الجدول لفترة زمنية كبيرة – وسيترك مستخدموك بدون خدمة.

لتجنب مثل هذه المشاكل، اتبع قاعدتين:

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

مشكلة أخرى: التحكم بالإصدارات والتراجع

أحيانًا تحتاج إلى التراجع عن تهجير.

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

كيف نصلح الأمر؟ استخدم الأدوات الصحيحة

لكل لغة وبيئة نظام لها أدوات تهجيرها الخاصة:

  • بالنسبة لجافا، Liquibase أو Flyway شائعة.
  • بالنسبة لـGo، الاختيار الشائع هو goose (التي سنلقي نظرة عليها هنا).
  • وهكذا.

Goose: ما هو ولماذا هو مفيد

Goose هو أداة خفيفة لـ Go تساعدك على إدارة التهجيرات تلقائيًا. إنها تقدم:

  • البساطة. قليلة الاعتمادات وهيكل ملف شفاف للتهجيرات.
  • التنوع. تدعم محركات قواعد البيانات المختلفة (PostgreSQL، MySQL، SQLite، إلخ).
  • المرونة. كتابة التهجيرات بلغة SQL أو Go.

تثبيت Goose

Shell

 

كيفية العمل: هيكل الهجرة

بشكل افتراضي، يبحث Goose عن ملفات الهجرة في db/migrations. كل هجرة تتبع هذا التنسيق:

Shell

 

  • NNN هو رقم الهجرة (مثلاً، 001، 002، إلخ).
  • بعد ذلك، يمكنك وضع أي اسم وصفي، مثل init_schema.
  • امتداد الملف يمكن أن يكون .sql أو .go.

مثال على هجرة SQL

ملف: 001_init_schema.sql:

SQL

 

مثالنا الأول

تغيير نوع العمود (سلسلة → عدد صحيح)

لنفترض أن لدينا جدول users بعمود يسمى age من نوع VARCHAR(255). الآن نريد تغييره إلى INTEGER. هكذا قد تبدو الهجرة (ملف 005_change_column_type.sql):

SQL

 

ما الذي يحدث هنا:

  1. هجرة الصعود

    • نقوم بتغيير عمود age إلى INTEGER. جملة USING (age::INTEGER) تخبر PostgreSQL كيفية تحويل البيانات الحالية إلى النوع الجديد.
    • يرجى ملاحظة أن هذه الهجرة ستفشل إذا كانت هناك بيانات في age ليست رقمية. في هذه الحالة، ستحتاج إلى استراتيجية أكثر تعقيداً (انظر أدناه).
  2. الهجرة التراجعية

    • إذا قمنا بالتراجع، نعيد age إلى VARCHAR(255).
    • نستخدم مرة أخرى USING (age::TEXT) للتحويل من INTEGER إلى نص.

الحالات الثانية والمعقدة: الهجرات متعددة الخطوات

إذا كانت عمود age قد يحتوي على بيانات غير منظمة (ليست أرقام فقط)، فمن الأكثر أمانًا القيام بذلك على عدة خطوات:

  1. إضافة عمود جديد (age_int) من نوع INTEGER.
  2. نسخ البيانات الصالحة إلى العمود الجديد، مع التعامل مع أو إزالة الإدخالات غير الصالحة.
  3. حذف العمود القديم.
SQL

 

للسماح بالتراجع السليم، فإن قسم Down يعكس ببساطة الإجراءات في الاتجاه المعاكس.

الأتمتة هي المفتاح

للتوفير في الوقت، من الملائم حقًا إضافة أوامر الهجرة إلى ملف Makefile (أو أي نظام بناء آخر). أدناه مثال على Makefile مع الأوامر الرئيسية لـ PostgreSQL.

دعنا نفترض:

  • أن DSN لقاعدة البيانات هو postgres://user:password@localhost:5432/dbname?sslmode=disable.
  • تتواجد ملفات الترحيل في db/migrations.
Shell

 

كيفية استخدامها؟

1. إنشاء ترحيل جديد (ملف SQL). يقوم هذا بإنشاء ملف db/migrations/002_add_orders_table.sql.

Shell

 

2. تطبيق جميع الترحيلات. ستقوم Goose بإنشاء جدول schema_migrations في قاعدة البيانات الخاصة بك (إذا لم تكن موجودة بالفعل) وتطبيق أي ترحيلات جديدة بترتيب تصاعدي.

Shell

 

3. إلغاء ترحيل الأخير. فقط إلغاء آخر واحد.

Shell

 

4. إلغاء جميع الترحيلات (استخدم بحذر في الإنتاج). إعادة تعيين كاملة.

Shell

 

5. فحص حالة الترحيل.

Shell

 

مثال على الناتج:

Shell

 

الملخص

من خلال استخدام أدوات الترحيل وملف Makefile، يمكننا:

  1. تقييد الوصول المباشر إلى قاعدة البيانات الإنتاجية، وإجراء التغييرات فقط من خلال الترحيلات.
  2. تتبع إصدارات قاعدة البيانات بسهولة وإلغاؤها إذا حدث خطأ ما.
  3. الحفاظ على تاريخ واحد وثابت لتغييرات قاعدة البيانات.
  4. تنفيذ ترحيلات “سلسة” التي لن تؤدي إلى كسر بيئة الإنتاج الحالية في عالم الخدمات المصغرة.
  5. الحصول على تحقق إضافي — كل تغيير سيمر بعملية PR ومراجعة الكود (بشرط وجود هذه الإعدادات).

ميزة أخرى هي أنه من السهل دمج جميع هذه الأوامر في خط أنابيب CI/CD الخاص بك. وتذكر — الأمان فوق كل شيء. 

على سبيل المثال:

YAML

 

الختام والنصائح

الأفكار الرئيسية بسيطة جدًا:

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

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

حظًا سعيدًا في تحريكاتك!

شكرًا على القراءة!

Source:
https://dzone.com/articles/goose-as-crucial-tool-for-your-service