قوانین 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
روند کلی باید اینطور باشد:
- نیاز به schema change مشخص شود.
- migration همراه همان task نوشته شود.
- migration داخل همان branch و همان MR قرار بگیرد.
- reviewer اثر migration روی data و deploy را بررسی کند.
- migration در pipeline محیطهای پایینتر اجرا و بررسی شود.
- 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_orderscreate_invoice_items_tableadd_index_to_transactions_reference_code
نمونه ضعیف:
fix_dbupdate_tablefinal_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 مناسب در این حالت معمولاً این است:
- schema جدید اضافه شود
- کد با هر دو ساختار قدیم و جدید سازگار شود
- data conversion بهصورت کنترلشده انجام شود
- بعد از کامل شدن conversion، بخش قدیمی حذف شود
در review چه چیزهایی باید دیده شود؟
هنگام review باید این سؤالها بررسی شوند:
- حجم داده چقدر است؟
- این conversion چقدر زمان میبرد؟
- آیا روی production lock یا فشار زیاد ایجاد میکند؟
- اگر وسط اجرا متوقف شود چه میشود؟
- آیا conversion تکرارپذیر است؟
- آیا rollback ممکن است یا فقط forward-fix داریم؟
مثال رایج: اضافه شدن field جدید همراه backfill
مثال:
- field جدید
approval_statusاضافه میشود - دادههای قبلی باید بر اساس چند شرط پر شوند
حالت اشتباه:
- migration هم column را بسازد
- هم همه dataهای قبلی را در همان لحظه با loop یا query سنگین تبدیل کند
حالت بهتر:
- column جدید اضافه شود
- کد بتواند موقتاً با مقدار خالی یا fallback کار کند
- backfill با job یا script جدا انجام شود
- بعد از کامل شدن 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 باشد
ترتیب اجرا
ترتیب کلی اجرا باید اینطور باشد:
- local
- stage
- 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 تبدیل میشود.