Mengapa Deployment Database Berbeda: Jaring Ketergantungan yang Tersembunyi
Anda memiliki database produksi yang sudah berjalan selama bertahun-tahun. Suatu hari, Anda perlu menambahkan kolom ke tabel orders. Kelihatannya sederhana. Aplikasi utama hanya membaca kolom yang dikenalnya, jadi kolom baru seharusnya tidak berbahaya.
Tapi kemudian batch job malam hari gagal. Laporan mingguan mulai menghasilkan angka yang kacau. Sebuah service milik tim lain tiba-tiba memunculkan error yang belum pernah Anda lihat sebelumnya.
Apa yang terjadi? Anda mengubah satu tabel, dan semuanya rusak.
Database Memiliki Lebih Banyak Konsumen dari yang Anda Kira
Di banyak organisasi, satu database jarang hanya melayani satu aplikasi. Seiring waktu, database tersebut mengakumulasi konsumen. Ada yang Anda ketahui. Ada yang sudah Anda lupakan. Ada yang dibangun oleh orang yang sudah keluar dari perusahaan bertahun-tahun lalu.
Berikut adalah gambaran tipikal database produksi yang mungkin melayani:
Diagram di bawah menunjukkan bagaimana satu database produksi terhubung ke banyak konsumen yang berbeda, masing-masing dengan pola aksesnya sendiri:
- Aplikasi web utama yang digunakan pelanggan
- Service API internal yang dikelola tim lain
- Batch job malam hari yang memproses ribuan baris
- Script pelaporan mingguan yang memberi data ke dashboard
- Query ad-hoc yang dijalankan tim data atau analis bisnis
- Service lawas yang tidak ingin disentuh siapa pun tetapi masih berjalan
Masing-masing konsumen ini mengakses database dengan cara berbeda. Aplikasi web mungkin membaca kolom status untuk menampilkan halaman. Batch job mungkin menulis ribuan baris menggunakan INSERT ... SELECT *. Script pelaporan mungkin bergantung pada view tertentu yang menggabungkan beberapa tabel. Analis mungkin memiliki query tersimpan yang mengharapkan kolom dalam urutan tertentu.
Saat Anda mengubah skema, Anda tidak hanya mengubahnya untuk aplikasi Anda. Anda mengubahnya untuk setiap konsumen ini.
Masalah Sebenarnya: Anda Tidak Tahu Siapa yang Bergantung pada Database Ini
Bagian tersulit dari perubahan skema database bukanlah pekerjaan teknisnya. Ini adalah masalah penemuan (discovery).
Dokumentasi seringkali tidak lengkap atau usang. Kode untuk aplikasi yang sudah tidak aktif mungkin masih tercantum sebagai konsumen. Batch job yang berjalan setahun sekali mudah terlewatkan. Service yang dikelola tim lain mungkin tidak pernah berkomunikasi dengan tim yang melakukan perubahan.
Anda tidak dapat mengubah sesuatu dengan aman jika Anda tidak memahaminya sepenuhnya.
Mengapa Backward Compatibility Itu Penting
Pendekatan teraman untuk perubahan skema adalah memastikan backward compatibility. Artinya, perubahan tersebut tidak boleh merusak kode yang ada yang belum diperbarui.
Berikut adalah pola praktis yang mengurangi risiko:
Kolom baru harus nullable atau memiliki nilai default. Kolom wajib tanpa nilai default akan merusak pernyataan INSERT apa pun yang tidak menyertakannya. Jika Anda harus menambahkan kolom wajib, tambahkan sebagai nullable terlebih dahulu, backfill data, lalu jadikan wajib dalam perubahan terpisah.
Hindari mengubah tipe kolom secara langsung. Sebagai gantinya, tambahkan kolom baru dengan tipe baru, migrasikan data secara bertahap, perbarui semua konsumen untuk menggunakan kolom baru, lalu hapus kolom lama. Proses ini bisa memakan waktu berminggu-minggu atau berbulan-bulan, tetapi mencegah downtime.
Hati-hati dengan SELECT *. Query yang memilih semua kolom dan memetakan hasil ke struktur data tetap akan rusak ketika kolom baru muncul. Jika Anda mengontrol kode yang mengonsumsi, ubah query ini untuk hanya memilih kolom yang mereka butuhkan. Jika Anda tidak mengontrol kode, Anda perlu berkoordinasi dengan tim pemilik.
Jangan hapus kolom atau tabel tanpa verifikasi. Kolom atau tabel yang tampaknya tidak digunakan mungkin dirujuk oleh script yang berjalan triwulanan. Periksa log query, kode aplikasi, dan bicarakan dengan tim lain sebelum menghapus apa pun.
Konsumen yang Terlupakan: Manusia
Aplikasi dan service bukan satu-satunya konsumen database Anda. Orang juga menjalankan query manual.
Tim data mungkin memiliki script yang menghasilkan laporan eksekutif bulanan. Analis bisnis mungkin memiliki query tersimpan di alat database mereka yang menarik data pelanggan setiap Senin pagi. Tim operasi mungkin menjalankan query ad-hoc selama respons insiden.
Saat Anda mengganti nama kolom atau menghapus tabel, query manual ini rusak secara diam-diam. Tidak ada yang menyadari sampai laporan keluar salah atau seseorang tidak dapat menemukan data yang mereka butuhkan selama gangguan.
Konsumen manusia ini lebih sulit dilacak karena mereka sering tidak muncul di repositori kode mana pun. Pertahanan terbaik adalah komunikasi. Sebelum melakukan perubahan skema, kirim pemberitahuan ke tim yang mungkin terpengaruh. Beri mereka tenggat waktu untuk menyampaikan kekhawatiran. Dokumentasikan perubahan di tempat yang dapat ditemukan orang.
Mengapa Rollback Database Tidak Seperti Rollback Aplikasi
Ketika deployment aplikasi salah, Anda dapat rollback ke versi sebelumnya. Kode lama menggantikan kode baru, dan sistem pulih.
Perubahan database tidak bekerja seperti ini.
Jika Anda menambahkan kolom dan kemudian perlu rollback, kolom tersebut tidak hilang secara otomatis. Data yang ditulis ke kolom itu tetap ada. Jika Anda mengubah tipe kolom dan kemudian rollback, data yang ada mungkin tidak cocok dengan tipe lama lagi. Jika Anda menghapus kolom, data akan hilang kecuali Anda memiliki cadangan.
Lebih buruk lagi, perubahan database yang bermasalah memengaruhi setiap konsumen secara bersamaan. Sementara rollback aplikasi hanya memengaruhi pengguna aplikasi tersebut, rollback database berdampak ke setiap service, script, dan orang yang menyentuh database.
Inilah mengapa deployment database memerlukan lebih banyak perencanaan, lebih banyak pengujian, dan lebih banyak koordinasi daripada deployment aplikasi. Radius ledakannya lebih besar, dan opsi pemulihannya lebih terbatas.
Checklist Praktis Sebelum Perubahan Skema Berikutnya
Sebelum Anda menjalankan ALTER TABLE di produksi, lakukan checklist ini:
- Daftar setiap aplikasi, service, dan script yang mengakses tabel ini
- Periksa query
SELECT *yang mungkin rusak - Verifikasi bahwa kolom baru memiliki default atau nullable
- Konfirmasi bahwa tidak ada kolom atau tabel yang dihapus masih digunakan
- Beri tahu tim yang mungkin menjalankan query manual terhadap tabel ini
- Miliki rencana rollback yang memperhitungkan data yang ditulis selama perubahan
- Uji perubahan di lingkungan staging yang mencerminkan konsumen produksi
Kesimpulan
Perubahan skema database bukan hanya masalah database. Ini adalah masalah koordinasi yang memengaruhi setiap konsumen yang terhubung ke database tersebut. Semakin banyak konsumen yang Anda miliki, semakin hati-hati Anda harus bersikap. Backward compatibility, penemuan menyeluruh, dan komunikasi yang jelas bukanlah opsional. Itulah perbedaan antara deployment yang mulus dan insiden produksi yang merusak banyak sistem sekaligus.