Kapan Anda Bisa Aman Menghapus Kolom Database Lama? Fase Kontrak dari Expand-Contract

Anda telah memigrasi semua kode aplikasi ke format kolom baru. Deployment berjalan mulus. Tidak ada error di log. Tim Anda siap membersihkan skema lama dan beralih ke fitur berikutnya.

Tapi, haruskah Anda menghapus kolom itu sekarang?

Jawabannya hampir selalu tidak. Menghapus struktur database lama terlalu cepat adalah salah satu penyebab paling umum insiden produksi yang tampak datang entah dari mana. Batch job yang berjalan sebulan sekali, query pelaporan yang ditulis seseorang enam bulan lalu, atau layanan lawas yang hanya aktif saat pemrosesan akhir kuartal—semua bisa gagal secara diam-diam hingga saat mereka benar-benar perlu dijalankan.

Fase terakhir dari pola expand-contract disebut fase kontrak. Namanya berasal dari gagasan mengecilkan atau menghapus struktur yang tidak lagi digunakan. Namun, mencapai fase ini membutuhkan lebih dari sekadar memastikan bahwa aplikasi utama Anda telah beralih.

Siapa Lagi yang Menyentuh Struktur Lama?

Sebelum Anda menghapus apa pun, Anda perlu menjawab satu pertanyaan: siapa lagi yang masih membaca atau menulis ke skema lama?

Aplikasi utama Anda mungkin sudah pindah. Tapi, bisa ada konsumen lain yang belum Anda pikirkan:

  • Batch job malam hari yang masih mereferensi kolom lama
  • Query manual yang dijalankan tim data untuk analisis ad-hoc
  • Sistem pelaporan yang menghasilkan PDF bulanan menggunakan tabel lama
  • Alat internal yang di-deploy enam bulan lalu dan belum diperbarui
  • Integrasi pihak ketiga yang mengirim data dalam format lama

Ketergantungan ini mudah terlewat karena tidak mengikuti siklus deployment yang sama dengan aplikasi utama Anda. Mereka bahkan mungkin tidak berada di repositori yang sama. Beberapa di antaranya mungkin bukan kode sama sekali—bisa berupa skrip SQL yang disimpan di laptop seseorang.

Cara Mendeteksi Ketergantungan Tersembunyi

Cara paling sederhana untuk menemukan ketergantungan ini adalah dengan memeriksa log database Anda. Database seperti PostgreSQL, MySQL, dan Oracle semuanya mencatat query yang berjalan terhadapnya. Anda dapat memfilter query yang mereferensi kolom atau tabel yang ingin Anda hapus.

Diagram alir berikut merangkum proses keputusan untuk menentukan apakah aman menghapus kolom lama:

flowchart TD A[Berencana menghapus kolom lama?] --> B{Apakah ada batch job?} B -->|Ya| C[Jangan hapus dulu] B -->|Tidak| D{Apakah ada query pelaporan?} D -->|Ya| C D -->|Tidak| E{Apakah ada alat internal?} E -->|Ya| C E -->|Tidak| F{Apakah ada integrasi pihak ketiga?} F -->|Ya| C F -->|Tidak| G[Hapus kolom]

Jika database Anda tidak mencatat query secara default, Anda dapat mengaktifkannya sementara. PostgreSQL memiliki pg_stat_statements untuk melacak statistik query. MySQL memiliki Performance Schema. Keduanya dapat menunjukkan query mana yang masih menyentuh struktur lama.

Pendekatan kedua adalah memantau error setelah aplikasi Anda beralih. Jika sesuatu masih mencoba menulis ke kolom lama, Anda kemungkinan akan melihat error di log aplikasi. Tapi ini hanya menangkap konsumen aktif. Skrip yang berjalan sekali seperempat mungkin tidak memicu error selama berbulan-bulan.

Inilah mengapa periode tunggu sebelum penghapusan itu penting. Beberapa tim menunggu satu siklus deployment penuh—biasanya dua minggu setelah semua aplikasi beralih. Yang lain menunggu lebih lama, terutama ketika ada query manual atau laporan yang dijalankan oleh tim non-teknis. Tidak ada aturan universal, tetapi semakin banyak ketergantungan yang tidak terkendali yang Anda miliki, semakin lama Anda harus menunggu.

Penghapusan Sebenarnya

Setelah Anda yakin tidak ada ketergantungan yang tersisa, Anda dapat melanjutkan penghapusan. Perintah SQL-nya sederhana:

Berikut adalah contoh praktis SQL yang akan Anda jalankan, beserta query untuk memverifikasi bahwa tidak ada objek database lain yang masih bergantung pada kolom tersebut:

-- Pertama, periksa view, fungsi, atau trigger yang mereferensi kolom
SELECT DISTINCT
    OBJECT_SCHEMA,
    OBJECT_NAME,
    OBJECT_TYPE
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%old_column_name%'
UNION
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    'VIEW'
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION LIKE '%old_column_name%';

-- Setelah dipastikan aman, hapus kolom
ALTER TABLE users DROP COLUMN old_legacy_status;

-- Bersihkan indeks yang hanya ada untuk kolom lama
DROP INDEX IF EXISTS idx_old_status ON users;

Jalankan pemeriksaan ketergantungan terlebih dahulu, lalu lanjutkan dengan drop. Jika pemeriksaan mengembalikan baris apa pun, Anda telah menemukan konsumen tersembunyi yang perlu diperbarui sebelum Anda dapat menghapus dengan aman.

  • Untuk kolom: ALTER TABLE ... DROP COLUMN
  • Untuk tabel: DROP TABLE
  • Untuk constraint: ALTER TABLE ... DROP CONSTRAINT

Tapi urutannya penting. Hapus kolom atau tabel yang paling kecil kemungkinannya digunakan terlebih dahulu, lalu tunggu beberapa hari sebelum menghapus sisanya. Pendekatan bertahap ini memberi Anda jaring pengaman. Jika sesuatu rusak setelah penghapusan pertama, Anda masih punya waktu untuk bereaksi sebelum struktur yang lebih kritis hilang.

Jangan Lupakan Indeks dan Trigger

Satu hal yang sering terlewatkan adalah membersihkan objek database terkait. Indeks yang hanya ada untuk kolom lama harus dihapus. Trigger yang mereferensi tabel lama harus dihilangkan. Jika Anda meninggalkannya, database Anda akan menumpuk beban mati yang dapat memperlambat penulisan dan mempersulit migrasi di masa depan.

Daftar periksa cepat sebelum Anda menyelesaikan fase kontrak:

  • Konfirmasi tidak ada query aktif yang menyentuh struktur lama (periksa log selama setidaknya satu siklus penuh)
  • Verifikasi semua batch job, laporan, dan skrip manual telah diperbarui
  • Hapus indeks yang hanya melayani kolom lama
  • Hapus trigger yang mereferensi tabel lama
  • Hapus secara bertahap: yang paling tidak berisiko terlebih dahulu, tunggu, lalu lanjutkan
  • Pantau error aplikasi selama 24-48 jam setelah setiap penghapusan

Inti Sebenarnya

Fase kontrak bukan tentang kecepatan. Ini tentang keyakinan. Menghapus skema lama terlalu cepat memperkenalkan risiko yang sulit dideteksi sampai semuanya terlambat. Periode tunggu tambahan bukanlah waktu yang terbuang—itu adalah penyangga keamanan Anda terhadap ketergantungan tersembunyi yang tidak Anda ketahui keberadaannya.

Setelah skema lama hilang, pola expand-contract selesai. Anda telah menambahkan struktur baru, memigrasi semua konsumen, dan menghapus yang lama dengan aman tanpa menyebabkan insiden produksi. Itulah inti dari pola ini: membuat perubahan database cukup aman sehingga tim Anda tidak takut melakukannya.