Kapan Down Migration Database Aman dan Kapan Berbahaya
Anda baru saja menerapkan migrasi database yang menambahkan kolom phone_number ke tabel users. Beberapa jam kemudian, seseorang menyadari bahwa nama kolom seharusnya phone agar konsisten dengan kodebase lainnya. Insting pertama Anda adalah menjalankan down migration, menghapus kolom tersebut, dan menerapkan ulang dengan nama yang benar. Sederhana, bukan?
Pada tahap awal pengembangan, itu berjalan dengan baik. Di production, tindakan yang sama bisa mengakibatkan hilangnya data pelanggan, memicu error aplikasi, dan menciptakan kekacauan yang butuh waktu berhari-hari untuk diurai.
Down migration adalah padanan database dari operasi undo. Jika migrasi Anda menambahkan kolom, down migration akan menghapusnya. Jika migrasi Anda membuat tabel, down migration akan menghapusnya. Konsepnya terdengar sederhana, tetapi konsekuensinya tidak sesederhana itu begitu pengguna nyata dan data nyata terlibat.
Down Migration Aman di Tahap Awal Pengembangan
Ketika tim Anda sedang membangun fitur baru di sebuah branch, skema bisa berubah beberapa kali dalam sehari. Anda menulis migrasi, mengujinya, menyadari pendekatannya salah, lalu menjalankan down migration. Tidak ada yang terpengaruh karena belum ada pengguna. Tidak ada kode lain yang bergantung pada skema tersebut karena Anda bekerja secara terisolasi.
Di sinilah down migration bersinar. Mereka memungkinkan Anda bereksperimen dengan cepat tanpa khawatir tentang pembersihan. Anda dapat mencoba tipe kolom yang berbeda, menguji struktur tabel, dan melakukan iterasi dengan cepat. Biaya kesalahan adalah nol karena belum ada yang permanen.
Staging Memperkenalkan Risiko Nyata Pertama
Lingkungan staging berada di area abu-abu. Down migration masih berfungsi di sini, tetapi mulai menunjukkan sisi berbahayanya.
Masalahnya adalah data. Lingkungan staging sering berisi data mirip production, baik dari backup anonim maupun dari penggunaan nyata selama pengujian. Jika down migration Anda menghapus kolom, Anda kehilangan data apa pun yang ada di kolom tersebut. Di staging, Anda biasanya bisa memuat ulang data, tetapi prosesnya memakan waktu. Tabel dengan jutaan baris mungkin butuh waktu berjam-jam untuk dibangun ulang.
Yang lebih penting, staging membentuk kebiasaan. Jika tim Anda terbiasa menjalankan down migration di staging setiap hari, memori otot itu terbawa ke production. Tindakan yang sama yang tidak berbahaya di staging menjadi destruktif di production, dan tidak ada yang berhenti untuk memikirkannya karena "kita selalu melakukan ini."
Production: Tempat Down Migration Menjadi Berbahaya
Production adalah tempat konsep sederhana "undo" mulai runtuh. Tiga masalah spesifik membuat down migration berisiko di lingkungan production.
Diagram state berikut mengilustrasikan bagaimana keamanan down migration berubah di berbagai lingkungan:
Pertimbangkan migrasi ini yang menambahkan kolom phone_number ke tabel users:
-- Up migration
ALTER TABLE users ADD COLUMN phone_number varchar(20);
-- Down migration
ALTER TABLE users DROP COLUMN phone_number;
Jika pengguna sudah memasukkan nomor telepon mereka, menjalankan down migration akan menghancurkan data itu secara instan. Tanpa peringatan, tanpa konfirmasi, tanpa undo. Kolom dan semua nilainya hilang.
Kehilangan Data Bersifat Permanen
Ketika Anda menjalankan down migration yang menghapus kolom, setiap nilai di kolom tersebut hilang. Tidak ada tempat sampah untuk kolom database. Jika migrasi Anda menambahkan kolom phone_number dan pengguna sudah memasukkan nomor mereka, nomor-nomor itu menghilang saat kolom dihapus.
Anda mungkin berpikir, "Saya akan restore dari backup." Tetapi backup yang diambil setelah migrasi berjalan sudah berisi kolom baru dengan data baru. Restore dari backup yang diambil sebelum migrasi berarti Anda kehilangan semua perubahan yang terjadi setelah migrasi berjalan. Either way, data hilang.
Satu-satunya pendekatan aman adalah restore dari backup yang diambil sebelum migrasi, lalu memutar ulang setiap perubahan yang terjadi setelah migrasi, tidak termasuk migrasi yang bermasalah itu sendiri. Proses itu rumit, memakan waktu, dan rawan error. Sebagian besar tim tidak memiliki peralatan atau disiplin operasional untuk melakukannya dengan andal.
Kode dan Skema Menjadi Tidak Sinkron
Ini adalah pola kegagalan production yang paling umum dengan down migration. Bayangkan migrasi Anda menambahkan kolom status ke tabel orders dengan nilai default pending. Kode aplikasi baru Anda membaca kolom ini. Ketika Anda menjalankan down migration, kolom tersebut menghilang.
Tetapi instance aplikasi Anda masih menjalankan kode baru. Mereka langsung mulai melempar error karena kolom yang mereka harapkan tidak lagi ada. Bahkan jika Anda mulai melakukan rollback kode aplikasi, rollback tidak instan. Anda memiliki beberapa instance, masing-masing dengan siklus deployment sendiri. Beberapa instance mungkin masih menjalankan kode baru sementara yang lain sudah di-rollback. Selama jendela itu, error mengalir ke seluruh sistem Anda.
Masalah fundamentalnya adalah rollback aplikasi dan rollback database tidak dapat disinkronkan dengan sempurna. Akan selalu ada periode di mana kode mengharapkan skema yang tidak lagi ada, atau skema memiliki kolom yang tidak diketahui cara menangani oleh kode lama.
Beberapa Perubahan Tidak Dapat Dibalikkan
Migrasi tertentu bersifat destruktif secara alami. Pertimbangkan migrasi yang menggabungkan first_name dan last_name menjadi satu kolom full_name. Data asli telah diubah. Menjalankan down migration dapat membuat ulang kolom first_name dan last_name, tetapi data di dalamnya tidak akan cocok dengan apa yang ada sebelum migrasi. Pemisahan asli hilang.
Contoh lain: migrasi yang menghapus kolom yang masih digunakan oleh query lama. Begitu kolom itu dihapus, data hilang. Tidak ada keajaiban down migration yang bisa mengembalikannya. Satu-satunya jalur pemulihan adalah restore dari backup, yang membawa kembali semua masalah yang disebutkan sebelumnya.
Kapan Down Migration Dapat Diterima di Production
Down migration tidak sepenuhnya dilarang di production. Ada kondisi spesifik di mana mereka dapat digunakan dengan aman:
- Migrasi hanya menambahkan tabel atau kolom baru yang belum pernah diisi data.
- Belum ada kode aplikasi yang di-deploy yang bergantung pada skema baru.
- Anda dapat memverifikasi bahwa tidak ada proses yang berjalan, job terjadwal, atau worker latar belakang yang mereferensi skema yang diubah.
Bahkan dalam kasus ini, pendekatan teraman adalah memperlakukan down migration sebagai forward migration baru. Tulis migrasi yang secara eksplisit membalikkan perubahan, deploy, dan biarkan berjalan melalui pipeline normal Anda. Ini memberikan hasil yang sama dengan down migration, tetapi dengan visibilitas penuh, pengujian, dan kemampuan rollback.
Checklist Praktis Sebelum Menjalankan Down Migration di Production
Sebelum Anda menjalankan down migration itu, tanyakan pertanyaan-pertanyaan ini:
- Apakah ada data pengguna di kolom atau tabel yang akan dihapus?
- Apakah ada instance aplikasi yang masih menjalankan kode yang bergantung pada skema ini?
- Apakah ada job latar belakang, tugas terjadwal, atau pipeline data yang mereferensi objek yang diubah?
- Dapatkah perubahan dibalikkan tanpa kehilangan informasi yang dimasukkan setelah migrasi?
- Apakah Anda memiliki backup terverifikasi yang diambil sebelum migrasi berjalan?
- Dapatkah Anda menanggung downtime saat down migration berjalan di tabel besar?
Jika Anda menjawab "ya" untuk salah satu dari tiga pertanyaan pertama, jangan jalankan down migration. Tulislah forward migration sebagai gantinya.
Alternatif yang Lebih Aman: Maju ke Depan, Bukan Mundur ke Belakang
Strategi paling andal untuk memperbaiki migrasi database yang buruk di production bukanlah dengan mengundonya, tetapi memperbaikinya ke depan. Tulislah migrasi baru yang memperbaiki masalah. Jika nama kolom salah, tambahkan kolom yang benar, salin data, dan depresiasi yang lama. Jika perubahan skema memperkenalkan bug, tambahkan migrasi yang menyesuaikan skema ke keadaan yang benar.
Forward migration lebih aman karena mereka mempertahankan data yang ada, menjaga kompatibilitas dengan kode yang berjalan, dan mengikuti proses deployment yang sama seperti perubahan lainnya. Mereka tidak memerlukan sinkronisasi sempurna antara rollback aplikasi dan database. Mereka tidak menciptakan jendela inkonsistensi di mana error menyebar ke seluruh sistem Anda.
Down migration adalah alat development. Di production, maju ke depan selalu lebih aman daripada mundur ke belakang.