Mengapa Deployment Database Lebih Sulit daripada Deployment Aplikasi

Anda mungkin sudah sepekan ini melakukan deployment kode aplikasi. Fitur baru masuk, proses lama berhenti, proses baru berjalan. Jika ada yang rusak, Anda tinggal kembali ke versi sebelumnya. Seluruh siklus hanya memakan waktu menit. Rasanya aman karena kode bisa diganti.

Lalu tibalah migrasi database. Kolom baru perlu ditambahkan. Tabel perlu diganti namanya. Anda menjalankan skrip migrasi, dan tiba-tiba database produksi memiliki struktur yang berbeda. Aplikasi awalnya berjalan baik, tapi satu jam kemudian seseorang melaporkan data hilang di sebuah laporan. Anda mencoba rollback migrasi, tetapi data yang sudah diubah selama migrasi tidak kembali bersih. Beberapa baris masih memiliki struktur baru. Beberapa nilai lama sudah hilang.

Inilah momen ketika banyak tim menyadari bahwa deployment database bukan sekadar "deployment untuk jenis hal yang berbeda". Ini adalah masalah yang secara fundamental berbeda.

Kode Itu Sekali Pakai, Data Tidak

Saat pertama kali belajar membuat aplikasi, Anda mungkin menganggap aplikasi sebagai kumpulan kode. Anda menulis kode, menjalankannya, melihat hasilnya, dan mengubah kode lagi jika ada yang salah. Jika versi baru tidak berfungsi, Anda kembali ke versi sebelumnya. Proses ini terasa ringan karena tidak ada konsekuensi jangka panjang. Kode yang salah bisa dibuang, diganti, atau ditulis ulang dari awal.

Namun, ketika aplikasi mulai digunakan oleh orang lain, sesuatu tumbuh bersamanya: data. Data pengguna, data transaksi, data pesanan, catatan histori. Data ini bukan sekadar isi database. Data adalah catatan tentang apa yang telah terjadi dalam bisnis. Setiap baris di tabel menyimpan sesuatu yang berharga. Jika data hilang, menulis ulang kode tidak akan mengembalikannya. Data yang hilang tidak bisa dihasilkan ulang.

Inilah perbedaan mendasar antara kode aplikasi dan database. Kode aplikasi bisa diperlakukan sebagai artefak yang dapat diganti. Anda bisa menghapus folder proyek, clone lagi dari repositori, dan aplikasi akan berjalan persis seperti sebelumnya. Tapi database tidak seperti itu. Database menyimpan state, yaitu kondisi terkini dari data bisnis. State ini terbentuk dari akumulasi operasi yang telah terjadi. Jika database dihapus, state-nya hilang. Tidak ada Git clone yang bisa mengembalikan data pelanggan yang terkumpul selama setahun.

Dampak pada Deployment

Efek dari perbedaan ini langsung terasa saat deployment. Ketika Anda men-deploy versi baru aplikasi, Anda mengirim kode terbaru ke server, menghentikan proses lama, dan memulai yang baru. Jika versi baru bermasalah, Anda bisa rollback dengan kembali ke versi sebelumnya. Aplikasi akan berjalan seperti sebelum pembaruan.

Namun, ketika deployment database mengubah struktur tabel, data yang sudah ada ikut terpengaruh. Kolom baru mungkin diisi dengan nilai default. Tipe data mungkin berubah. Data lama mungkin perlu ditransformasi. Jika perubahan ini menyebabkan masalah, rollback tidak sesederhana menukar versi kode. Data yang sudah diubah tidak otomatis kembali ke bentuk aslinya.

Pertimbangkan migrasi sederhana yang menambahkan kolom dan mengisinya dengan data:

-- Forward migration
ALTER TABLE users ADD COLUMN age INT;
UPDATE users SET age = 25 WHERE age IS NULL;
-- Rollback script
ALTER TABLE users DROP COLUMN age;

Jika forward migration sudah berjalan dan aplikasi mulai menulis usia baru, rollback akan menghapus kolom tersebut dan nilai-nilai baru itu hilang. Tidak seperti kode aplikasi, Anda tidak bisa sekadar men-deploy ulang versi lama untuk memulihkan data yang hilang.

Inilah mengapa banyak tim menjadi hati-hati dengan deployment database. Mereka bisa dengan cepat menukar versi aplikasi beberapa kali sehari, tapi ragu menjalankan migrasi database di setiap deploy. Bukan karena migrasi secara teknis sulit, tapi karena konsekuensinya berbeda. Kode yang salah bisa diperbaiki dengan menulis ulang. Data yang salah mungkin butuh waktu berhari-hari untuk diperbaiki, dan terkadang tidak bisa dikembalikan persis seperti sebelumnya.

Bagaimana Ini Mengubah Proses Deployment Anda

Perbedaan antara kode dan data memengaruhi cara Anda mendesain proses deployment. Untuk aplikasi, Anda terutama perlu memastikan kode baru bisa berjalan. Untuk database, Anda harus memastikan perubahan struktural tidak merusak data yang ada, tidak mengganggu aplikasi yang sedang berjalan, dan masih bisa dibatalkan jika terjadi kesalahan.

Berikut implikasi praktisnya:

Deployment aplikasi bersifat aditif. Anda menambahkan kode baru, menghapus kode lama, dan sistem terus berjalan. Versi lama masih tersedia di repositori atau penyimpanan artefak.

Deployment database bersifat transformatif. Anda mengubah struktur data yang sudah ada. Struktur lama hilang begitu migrasi berjalan. Meskipun Anda punya backup, mengembalikannya berarti kehilangan data apa pun yang dibuat setelah backup diambil.

Rollback aplikasi murah. Anda mengarahkan load balancer ke versi lama, atau memulai ulang proses lama. State aplikasi ditentukan oleh kode yang sedang berjalan.

Rollback database mahal. Anda perlu menulis migrasi balik yang mentransformasi data kembali ke struktur sebelumnya. Migrasi balik ini harus diuji. Mungkin gagal jika data baru telah ditambahkan yang tidak cocok dengan struktur lama. Dan jika forward migration mentransformasi data secara ireversibel (misalnya, menggabungkan nama depan dan belakang menjadi satu kolom), migrasi balik mungkin kehilangan informasi.

Risiko Sebenarnya Bukan Teknis

Banyak tim memperlakukan migrasi database sebagai masalah teknis murni. Mereka menulis skrip migrasi, mengujinya di staging, dan menjalankannya di produksi. Ketika terjadi kesalahan, mereka menyalahkan skrip migrasi atau alat database.

Tapi risiko sebenarnya seringkali bersifat organisasional. Migrasi database menyentuh data milik pengguna nyata. Kesalahan bisa merusak catatan pelanggan, data keuangan, atau log kepatuhan. Tim yang menjalankan migrasi mungkin tidak sepenuhnya memahami bagaimana data digunakan oleh sistem lain. Perubahan nama kolom bisa merusak query pelaporan yang berjalan sebulan sekali. Perubahan tipe data bisa menyebabkan layanan lama gagal secara diam-diam.

Inilah mengapa deployment database memerlukan tingkat kehati-hatian yang berbeda. Kompleksitas teknis masih bisa dikelola. Kompleksitas organisasional lah yang membuat tim melambat.

Daftar Periksa Praktis untuk Deployment Database

Sebelum menjalankan migrasi database di produksi, pertimbangkan pemeriksaan ini:

  • Dapatkah migrasi dibalikkan? Tulis dan uji skrip rollback sebelum menjalankan forward migration.
  • Apakah migrasi akan merusak aplikasi saat ini? Jika aplikasi membaca dari kolom yang Anda ganti namanya, aplikasi akan gagal sampai aplikasi itu juga diperbarui.
  • Dapatkah migrasi berjalan saat aplikasi aktif? Beberapa migrasi mengunci tabel, yang dapat menyebabkan downtime.
  • Apakah ada backup? Ambil backup sebelum menjalankan migrasi apa pun yang mentransformasi data.
  • Siapa yang perlu tahu? Beri tahu tim yang menggunakan data ini, termasuk pelaporan, analitik, dan data science.

Kesimpulan

Kode aplikasi bersifat sekali pakai. Anda bisa membuangnya, menulis ulang, dan men-deploy versi baru tanpa kehilangan apa pun yang berarti. Data database tidak bersifat sekali pakai. Setiap migrasi mengubah sesuatu yang tidak bisa dengan mudah dibuat ulang.

Perlakukan deployment database dengan ketelitian yang sama seperti Anda menangani insiden produksi. Tulis skrip rollback. Uji migrasi dengan data realistis. Komunikasikan dengan tim yang bergantung pada data. Dan jangan pernah berasumsi bahwa migrasi aman hanya karena berhasil di staging.

Perbedaan antara kode dan data bukanlah detail teknis. Inilah alasan mengapa deployment database layak memiliki proses, strategi pengujian, dan penilaian risikonya sendiri.