Kenapa Database Butuh Pipeline CI/CD Sendiri
Anda sedang mengerjakan aplikasi yang digunakan oleh orang sungguhan setiap hari. Saat fitur baru perlu dirilis, Anda mengubah kode, mendorongnya melalui pipeline, dan versi baru pun terdeploy ke production. Jika ada yang salah, Anda rollback ke versi sebelumnya, dan semuanya kembali normal dalam hitungan menit. Proses ini terasa mulus karena aplikasi Anda tidak membawa data penting di dalam kodenya sendiri.
Sekarang bayangkan Anda perlu menambahkan satu kolom ke tabel user. Di laptop Anda, Anda menjalankan ALTER TABLE user ADD COLUMN ... dan selesai. Tapi di production, tabel itu berisi jutaan baris data pengguna asli. Aplikasi membaca dan menulis ke tabel itu setiap detik. Beberapa query mungkin rusak jika kolom baru mengubah struktur indeks. Koneksi database bisa timeout jika operasi alter berjalan terlalu lama.
Inilah perbedaan fundamental yang membuat perubahan database sangat berbeda dari perubahan aplikasi. Dan inilah mengapa memperlakukan migrasi database seperti deployment kode biasa pada akhirnya akan menyebabkan masalah nyata.
Stateless vs Stateful: Perbedaan Inti
Aplikasi bersifat stateless. Anda bisa mematikan sebuah instance, menggantinya dengan yang baru, atau rollback ke versi lama tanpa kehilangan apa pun. Kode tidak peduli siapa yang menggunakannya sebelumnya. Setiap deployment adalah pertukaran yang bersih.
Database bersifat stateful. Mereka menyimpan data yang harus tetap utuh, konsisten, dan dapat diakses oleh pengguna aktif. Skema adalah kontrak antara aplikasi dan data Anda. Ketika kontrak itu berubah secara tiba-tiba atau tidak benar, data bisa rusak, aplikasi bisa mulai melempar error, dan pengguna bisa kehilangan akses.
Perbedaan ini mengubah segalanya tentang cara Anda menangani perubahan. Pipeline aplikasi tipikal memeriksa apakah kode bisa dibuild, apakah tes lulus, lalu deploy. Pipeline database perlu menjawab pertanyaan yang lebih sulit:
- Apakah perubahan skema ini kompatibel dengan versi aplikasi yang sedang berjalan?
- Akankah operasi ini mengunci tabel terlalu lama?
- Apakah data yang ada masih bisa dibaca setelah perubahan?
- Jika sesuatu gagal di tengah jalan, bagaimana cara kembali ke kondisi aman tanpa kehilangan data?
Masalah Waktu
Pipeline aplikasi bisa berjalan kapan saja, bahkan beberapa kali sehari. Anda push kode, pipeline berjalan, dan versi baru langsung live. Seluruh proses memakan waktu menit.
Pipeline database sering kali perlu berjalan pada waktu tertentu. Mungkin saat jam sibuk rendah. Mungkin setelah memastikan tidak ada transaksi berdurasi panjang yang sedang berlangsung. Mungkin hanya setelah persetujuan manual dari seseorang yang memahami beban kerja production.
Jika pipeline aplikasi gagal, Anda deploy ulang versi sebelumnya. Sederhana. Jika pipeline database gagal di tengah migrasi, Anda berakhir dengan migrasi parsial: setengah perubahan teraplikasi, setengahnya tidak. Ini adalah salah satu masalah paling rumit untuk ditangani, dan membutuhkan perencanaan yang cermat sebelum Anda menjalankan pipeline.
Kompatibilitas Bukan Opsional
Saat Anda deploy versi baru aplikasi, ia mengharapkan skema database tertentu. Saat Anda menjalankan migrasi, ia mengubah skema tersebut. Jika keduanya tidak selaras, semuanya rusak.
Tantangannya adalah selama deployment, versi lama dan baru aplikasi Anda mungkin berjalan bersamaan. Blue-green deployment, canary release, dan rolling update semuanya menciptakan jendela di mana beberapa versi aplikasi aktif. Skema database Anda harus kompatibel dengan semuanya pada saat yang sama.
Ini berarti Anda tidak bisa begitu saja menambahkan kolom dan langsung menggunakannya di deployment yang sama. Anda perlu pendekatan multi-langkah: pertama tambahkan kolom tanpa menggunakannya, deploy aplikasi, lalu mulai gunakan kolom tersebut di deployment berikutnya. Pola migrasi yang kompatibel ke belakang ini penting untuk deployment tanpa downtime, dan membutuhkan koordinasi antara pipeline aplikasi dan pipeline database Anda.
Kenapa Pipeline Terpisah
Anda mungkin tergoda untuk memasukkan migrasi database sebagai langkah di dalam pipeline aplikasi. Lagipula, keduanya adalah bagian dari pengiriman fitur. Tapi mencampurnya menciptakan beberapa masalah:
Diagram alir berikut menunjukkan bagaimana kedua pipeline berbeda dalam kompleksitas dan pemeriksaan keamanan:
Pipeline aplikasi Anda berjalan pada setiap perubahan kode. Migrasi database seharusnya hanya berjalan ketika skema benar-benar berubah. Menjalankan migrasi yang tidak perlu menambah risiko dan memperlambat deployment.
Rollback aplikasi itu sederhana. Rollback database tidak. Jika pipeline Anda menggabungkan keduanya, rollback aplikasi mungkin juga ikut mengembalikan perubahan database yang bisa menyebabkan kehilangan data.
Pipeline aplikasi itu cepat. Migrasi database bisa lambat, terutama pada tabel besar. Migrasi yang lambat bisa memblokir seluruh pipeline deployment Anda, menahan perubahan lain yang bahkan tidak menyentuh database.
Pipeline aplikasi mengasumsikan lingkungan stateless. Pipeline database perlu memahami status skema saat ini, volume data, dan beban kerja production. Ini adalah perhatian yang fundamental berbeda.
Seperti Apa Pipeline Database yang Baik
Pipeline database yang dirancang dengan baik tidak perlu rumit. Ia hanya perlu menghormati sifat sistem stateful. Inilah yang harus dilakukannya:
Jalankan setiap migrasi sebagai skrip yang dapat diulang, yang bisa ditinjau, diuji, dan dieksekusi secara konsisten. Setiap migrasi harus berupa satu file dengan nomor versi yang jelas, berisi langkah maju dan mundur.
Uji migrasi terhadap database yang sangat mirip dengan production. Tidak hanya dalam skema, tetapi juga dalam volume dan struktur data. Migrasi yang berjalan satu detik di database uji kosong mungkin memakan waktu dua puluh menit di production.
Jalankan migrasi dalam urutan yang terkontrol, satu per satu. Jangan pernah menggabungkan beberapa perubahan skema ke dalam satu operasi. Setiap migrasi harus kecil, fokus, dan dapat dibalikkan.
Verifikasi hasil setelah setiap migrasi. Periksa apakah skema sesuai ekspektasi, indeks sudah terpasang, dan data yang ada masih utuh.
Sediakan jalur yang jelas untuk maju atau mundur ketika ada yang salah. Ini berarti memiliki skrip rollback yang sudah diuji, mengetahui berapa lama waktu yang dibutuhkan, dan memahami data apa yang mungkin terpengaruh.
Daftar Periksa Praktis untuk Pipeline Database Anda
Sebelum Anda menyiapkan pipeline database, pastikan Anda bisa menjawab pertanyaan-pertanyaan ini:
- Bisakah setiap migrasi berjalan secara independen, atau tergantung pada migrasi lain yang berjalan terlebih dahulu?
- Apakah setiap migrasi dapat dibalikkan, dan sudahkah Anda menguji rollback-nya?
- Apakah migrasi berfungsi dengan versi aplikasi saat ini dan versi berikutnya?
- Berapa lama migrasi akan berjalan pada volume data production Anda?
- Apakah migrasi akan mengunci tabel, dan jika ya, berapa lama?
- Apa yang terjadi jika migrasi gagal di tengah jalan?
- Siapa yang perlu menyetujui menjalankan migrasi ini di production?
- Pada jam berapa migrasi ini harus berjalan?
- Bagaimana Anda akan memverifikasi bahwa migrasi berhasil?
Kesimpulan
Perubahan database bukanlah perubahan kode. Mereka beroperasi pada data langsung, memengaruhi pengguna aktif, dan membawa risiko nyata. Memperlakukannya seperti kode aplikasi pada akhirnya akan menyebabkan downtime, masalah data, atau keduanya. Pipeline terpisah untuk perubahan database memberi Anda kontrol, keamanan, dan prediktabilitas yang Anda butuhkan. Tidak harus rumit. Ia hanya harus dirancang untuk apa yang dikelolanya: data stateful berumur panjang yang diandalkan orang.