پرش به مطلب اصلی

قوانین Migration

هر تغییری که schema دیتابیس را تغییر می‌دهد، باید بر اساس این قواعد طراحی، review و اجرا شود.

ممکن است ابزار اجرای migration بین پروژه‌ها متفاوت باشد، اما منطق تصمیم‌گیری، flow اجرا و قواعد کنترل ریسک باید یکسان بماند.

هشدار

Migration فقط تغییر schema نیست. Migration روی data، availability، performance و deploy production اثر مستقیم دارد.

اصول پایه

  • migration باید قابل پیگیری باشد
  • migration باید قابل review باشد
  • migration باید روی داده موجود امن باشد
  • migration باید در deploy قابل کنترل باشد
  • migration باید در صورت نیاز rollback یا forward-fix مشخص داشته باشد

چه زمانی Migration لازم است؟

هر زمان schema دیتابیس تغییر می‌کند، migration لازم است.

نمونه:

  • ساخت table جدید
  • اضافه شدن field جدید
  • اضافه شدن index
  • اضافه شدن unique یا foreign key
  • rename کردن table یا column
  • حذف column یا table

اگر تغییر فقط در UI، service، validation یا API است و schema تغییر نمی‌کند، migration لازم نیست.

مالک Migration

قاعده اصلی:

  • کسی که contract داده را تغییر می‌دهد، مسئول نوشتن migration هم هست

یعنی اگر توسعه‌دهنده‌ای:

  • column جدید اضافه می‌کند
  • table جدید می‌سازد
  • نوع داده را تغییر می‌دهد
  • index یا constraint اضافه می‌کند

باید migration همان تغییر را هم خودش آماده کند.

مواردی که نیاز به review دقیق‌تر دارند:

  • جدول بزرگ
  • data migration سنگین
  • تغییر destructive
  • rename پرریسک
  • تغییری که روی چند سرویس یا consumer اثر دارد

در این موارد، فقط author کافی نیست و review فنی عمیق‌تر لازم است.

Flow

روند کلی باید این‌طور باشد:

  1. نیاز به schema change مشخص شود.
  2. migration همراه همان task نوشته شود.
  3. migration داخل همان branch و همان MR قرار بگیرد.
  4. reviewer اثر migration روی data و deploy را بررسی کند.
  5. migration در pipeline محیط‌های پایین‌تر اجرا و بررسی شود.
  6. migration در production فقط در مرحله deploy کنترل‌شده اجرا شود.

قاعده مهم:

  • هر task فقط migrationهای مربوط به همان task را دارد
  • migration جدا از task اصلی ساخته نمی‌شود مگر برای rollout برنامه‌ریزی‌شده

Migration در MR

اگر task شما migration دارد، MR باید این موضوع را صریح مشخص کند.

حداقل این موارد باید در Description ذکر شوند:

  • migration دارد یا ندارد
  • چه چیزی در schema تغییر می‌کند
  • آیا data موجود تحت تاثیر قرار می‌گیرد
  • rollback یا forward-fix چگونه است
  • آیا تغییر production-safe است یا rollout چندمرحله‌ای می‌خواهد

نمونه:

  • Database
    migration برای اضافه شدن approval_status
  • Risk
    low
  • Rollback
    قابل بازگشت از طریق down migration
  • Rollout
    یک‌مرحله‌ای

نوشتن Migration

  • migration باید کوچک و متمرکز باشد
  • migration باید فقط یک هدف روشن داشته باشد
  • نام migration باید action را توضیح دهد
  • business logic نباید داخل migration قرار بگیرد
  • data migration سنگین نباید بدون برنامه داخل migration اجرا شود

نمونه خوب:

  • add_approval_status_to_orders
  • create_invoice_items_table
  • add_index_to_transactions_reference_code

نمونه ضعیف:

  • fix_db
  • update_table
  • final_changes

تبدیل داده

تبدیل داده یکی از حساس‌ترین بخش‌های migration است.
منظور از تبدیل داده این است که علاوه بر تغییر schema، داده‌های قبلی هم باید به شکل جدید منتقل، بازنویسی یا استاندارد شوند.

نمونه:

  • پر کردن مقدار field جدید بر اساس داده قدیمی
  • تبدیل فرمت یک column
  • ادغام چند مقدار قدیمی در یک ساختار جدید
  • backfill کردن داده برای recordهای قبلی

چه زمانی قابل قبول است؟

تبدیل داده داخل migration فقط وقتی قابل قبول است که:

  • حجم داده کم باشد
  • اجرای آن سریع باشد
  • lock طولانی ایجاد نکند
  • rollback یا forward-fix آن روشن باشد
  • منطق آن ساده و قطعی باشد

نمونه مناسب:

  • مقداردهی پیش‌فرض برای چند record محدود
  • copy کردن مقدار یک column به column جدید در جدول کوچک
  • normalize کردن داده ساده با query محدود

چه زمانی نباید داخل migration باشد؟

در این شرایط، تبدیل داده نباید داخل migration اجرا شود:

  • تعداد recordها زیاد است
  • اجرای query زمان‌بر است
  • loop یا batch processing لازم است
  • به business rule پیچیده نیاز دارد
  • اجرای آن می‌تواند deploy را کند یا متوقف کند
  • برای تکمیل آن به چند مرحله rollout نیاز است

در این حالت، migration فقط باید schema را آماده کند و تبدیل داده از مسیر جدا انجام شود.

راه‌حل مناسب برای conversion سنگین

اگر تبدیل داده سنگین است، بهتر است از یکی از این راه‌ها استفاده شود:

  • job جداگانه
  • script کنترل‌شده
  • command اجرایی جدا
  • backfill مرحله‌ای
  • rollout چندمرحله‌ای

قاعده مهم:

  • schema change و data conversion لزوماً نباید در یک مرحله اجرا شوند

flow مناسب در این حالت معمولاً این است:

  1. schema جدید اضافه شود
  2. کد با هر دو ساختار قدیم و جدید سازگار شود
  3. data conversion به‌صورت کنترل‌شده انجام شود
  4. بعد از کامل شدن conversion، بخش قدیمی حذف شود

در review چه چیزهایی باید دیده شود؟

هنگام review باید این سؤال‌ها بررسی شوند:

  • حجم داده چقدر است؟
  • این conversion چقدر زمان می‌برد؟
  • آیا روی production lock یا فشار زیاد ایجاد می‌کند؟
  • اگر وسط اجرا متوقف شود چه می‌شود؟
  • آیا conversion تکرارپذیر است؟
  • آیا rollback ممکن است یا فقط forward-fix داریم؟

مثال رایج: اضافه شدن field جدید همراه backfill

مثال:

  • field جدید approval_status اضافه می‌شود
  • داده‌های قبلی باید بر اساس چند شرط پر شوند

حالت اشتباه:

  • migration هم column را بسازد
  • هم همه dataهای قبلی را در همان لحظه با loop یا query سنگین تبدیل کند

حالت بهتر:

  1. column جدید اضافه شود
  2. کد بتواند موقتاً با مقدار خالی یا fallback کار کند
  3. backfill با job یا script جدا انجام شود
  4. بعد از کامل شدن conversion، رفتار نهایی enforce شود
نکته

اگر تبدیل داده بدون آنکه deploy را متوقف کند، بدون lock سنگین و در زمان کوتاه انجام نمی‌شود، معمولاً جای آن داخل migration نیست.

تغییرات پرریسک

این موارد پرریسک محسوب می‌شوند:

  • drop column
  • drop table
  • rename بدون compatibility plan
  • تغییر type روی داده حجیم
  • افزودن index سنگین روی جدول بزرگ
  • data backfill سنگین

برای این موارد باید از قبل strategy مشخص باشد:

  • rollout چندمرحله‌ای
  • maintenance window در صورت نیاز
  • job یا script جدا برای backfill
  • rollback یا forward-fix روشن

CI/CD و اجرا

Migration باید بخشی از flow deploy باشد، نه یک کار دستی و فراموش‌شده.

قواعد اصلی:

  • migration باید در pipeline قابل اجرا باشد
  • اجرای migration باید reproducible باشد
  • اجرای migration در هر environment باید ثبت‌شده و قابل پیگیری باشد
  • اجرای migration در stage و production باید automated باشد

ترتیب اجرا

ترتیب کلی اجرا باید این‌طور باشد:

  1. local
  2. stage
  3. production

قبل از production باید مطمئن باشید:

  • migration بدون خطا اجرا می‌شود
  • کد و schema با هم سازگار هستند
  • اگر deploy نیمه‌کاره شد، وضعیت recovery روشن است

اجرای خودکار

قاعده اصلی:

  • اجرای migration در stage باید automated باشد
  • اجرای migration در production باید automated و بخشی از deploy کنترل‌شده باشد

یعنی stage و production نباید وابسته به اجرای دستی و خارج از pipeline باشند.

نکته

برای production مهم نیست migration با چه ابزار یا تکنولوژی‌ای نوشته شده است؛ مهم این است که execution آن قابل مشاهده، قابل تکرار و قابل مدیریت باشد.

مسئولیت‌ها

Author

  • migration را می‌نویسد
  • اثر آن را توضیح می‌دهد
  • risk و rollout را مشخص می‌کند
  • migration را همراه task اصلی نگه می‌دارد

Reviewer

  • صحت تغییر را بررسی می‌کند
  • اثر روی data و deploy را می‌سنجد
  • ریسک destructive بودن را تشخیص می‌دهد
  • درباره rollout و rollback سؤال درست می‌پرسد

CI/CD / Release Flow

  • migration را در مسیر استاندارد deploy اجرا می‌کند
  • نتیجه اجرا را قابل مشاهده نگه می‌دارد
  • اجرای environmentها را قابل پیگیری می‌کند

موارد ممنوع

  • migration خارج از MR
  • تغییر schema production بدون pipeline
  • اجرای دستی بدون ثبت
  • migration بدون owner مشخص
  • migration بدون درک اثر روی data
  • merge شدن migration پرریسک بدون review کافی

سناریوهای رایج

سناریو 1: field جدید

  • task: اضافه شدن approval_status
  • migration: add column
  • rollout: ساده
  • ریسک: کم

سناریو 2: rename پرریسک

  • task: تغییر نام یک column قدیمی
  • migration: rename
  • rollout: ممکن است چندمرحله‌ای باشد
  • ریسک: متوسط تا زیاد

سناریو 3: backfill سنگین

  • task: تولید مقدار برای داده‌های قبلی
  • migration: فقط schema
  • backfill: job یا script جدا
  • ریسک: زیاد

جمع‌بندی

  • migration باید همراه همان task طراحی و review شود
  • migration باید production-safe باشد
  • migration پرریسک بدون strategy مشخص merge نمی‌شود
  • اجرای migration در stage و production باید automated باشد

هرجا migration باعث ابهام در rollout، rollback یا data conversion می‌شود، هنوز برای merge آماده نیست.

جمع‌بندی

Migration در همه پروژه‌ها باید از یک policy پیروی کند:

  • migration را author همان task می‌نویسد
  • migration داخل همان MR بررسی می‌شود
  • migration در CI/CD اجرا می‌شود
  • production execution باید کنترل‌شده باشد
  • migration پرریسک بدون strategy مشخص merge نمی‌شود

اگر این قواعد رعایت نشوند، migration از یک ابزار deployment-safe به یک ریسک production تبدیل می‌شود.