Kelola siklus hidup data
Retensi, arsip, penghapusan lunak, penghapusan permanen, dan salinan turunan: siapa yang memegang data, berapa lama, dan bagaimana ia benar-benar hilang.
Pertanyaan
Berapa lama tiap jenis data disimpan, di mana saja ia ada, dan bagaimana ia benar-benar dihapus?
Setelah baca ini, kamu bisa menulis kebijakan retensi per jenis data, memilih antara soft delete dan hard delete, dan menelusuri semua salinan turunan yang ikut harus ditangani.
Prasyarat dan contoh
Kamu sudah bisa memodelkan skema (M04.01), memilih keluarga penyimpanan (M04.02), dan mengubah skema dengan aman (M04.05).
Tabel events menerima 800 baris per detik, sekitar 69 juta per hari. Dengan rata-rata 300 byte
per baris, itu sekitar 20 GB per hari, atau 7,5 TB per tahun, belum termasuk indeks. Tanpa
kebijakan, disk penuh dalam hitungan bulan dan query jadi lambat karena tabel membengkak.
Sementara itu pengguna meminta akunnya dihapus. Data mereka ada di tabel utama, cache, indeks
pencarian, dan backup.
Data punya umur. Menyimpan selamanya bukan kebijakan, itu ketiadaan kebijakan.
Mekanisme
Retensi per jenis data. Tiap jenis punya alasan simpan dan batas waktu yang berbeda:
| Data | Alasan simpan | Contoh retensi | | --------------------- | ------------------------ | ---------------------------------- | | Event klik mentah | Analitik jangka pendek | 90 hari, lalu hanya agregat | | Order dan faktur | Kewajiban hukum dan audit | Bertahun-tahun, sesuai regulasi | | Log akses | Debug dan keamanan | 30 hari | | Sesi kedaluwarsa | Tidak ada | Hapus saat kedaluwarsa |
Angka retensi harus datang dari kebutuhan bisnis dan hukum, bukan dari tebakan engineer. Contoh di atas ilustrasi.
Partisi menurut waktu untuk membuang data lama murah. DELETE FROM events WHERE created_at < now() - interval '90 days' atas ratusan juta baris itu mahal: menulis banyak WAL, meninggalkan
baris mati yang harus di-vacuum, dan menekan I/O. Kalau tabel dipartisi per hari, membuang hari
ke-91 cukup DROP satu partisi, operasi metadata yang hampir instan.
Arsip. Pindahkan data dingin ke penyimpanan murah (misalnya berkas terkompresi di object storage) sebelum menghapusnya dari store utama. Putuskan sejak awal apakah arsip bisa dibaca kembali, siapa yang boleh, dan seberapa lambat. Arsip yang tidak pernah diuji pemulihannya hanyalah dugaan.
Soft delete vs hard delete.
- Soft delete: tandai
deleted_at, baris tetap ada. Memungkinkan undo dan jejak audit. Harganya: setiap query harus ingatWHERE deleted_at IS NULL, unique constraint bisa bentrok (email yang "sudah dihapus" tetap menempati unique index kecuali dibuat parsial), dan data tetap ada. - Hard delete: baris benar-benar dibuang. Sederhana, tapi tidak bisa dibatalkan kecuali dari backup.
Soft delete bukan penghapusan untuk keperluan privasi. Kalau pengguna berhak data mereka hilang, soft delete saja tidak memenuhi itu. Pola umum: soft delete dengan masa tenggang 30 hari, lalu hard delete oleh job terjadwal.
Salinan turunan. Satu data bisa ada di banyak tempat: cache, indeks pencarian, warehouse analitik, replika, log, dan backup. Penghapusan harus memperhitungkan masing-masing:
- Cache: hapus atau biarkan kedaluwarsa dengan TTL yang ditentukan.
- Indeks pencarian dan warehouse: butuh event penghapusan yang dikirim ke sana, dan cara memastikannya sampai.
- Backup: biasanya tidak dimodifikasi satu per satu. Kebijakannya sering "data terhapus dari backup setelah siklus retensi backup selesai, misalnya 35 hari". Dan kalau backup dipulihkan, daftar penghapusan harus diterapkan ulang.
Saat rancangan ini gagal
- Retensi tak terbatas by default. Tabel log tumbuh sampai query jadi lambat dan biaya
penyimpanan meledak, lalu pembersihannya dilakukan darurat dengan
DELETEbesar yang menjatuhkan layanan. - Soft delete yang bocor. Satu query baru lupa filter
deleted_at, dan data yang "dihapus" muncul di halaman pengguna lain. - Hapus di sumber, lupa turunan. Pengguna dihapus dari database, tapi masih muncul di hasil pencarian dan email mingguan karena indeks dan daftar penerima tidak diperbarui.
- Arsip tanpa uji pemulihan. Setahun kemudian audit meminta data lama, dan formatnya sudah tidak bisa dibaca karena skema berubah.
- Cascade delete tak terkendali.
ON DELETE CASCADEdariuserske semua tabel anak menghapus ratusan ribu baris dalam satu transaksi dan memblokir tabel.
Contoh tandingan: soft delete untuk setiap tabel sering berlebihan. Tabel sesi dan token sementara cukup hard delete, dan soft delete di sana hanya menambah beban query dan ukuran tabel.
Latihan
Aplikasi catatan punya tabel notes (50 juta baris), cache per pengguna, indeks pencarian
terpisah, dan backup harian yang disimpan 30 hari. Pengguna menekan "hapus akun". Rancang alur
penghapusan, dan sebutkan apa yang tersisa dan berapa lama.
Lihat pembahasan
Alur:
- Segera: tandai akun
deleted_atdan cabut sesi. Pengguna tidak bisa login, dan semua query publik sudah memfilter akun yang ditandai. Ini memberi masa tenggang jika pengguna menyesal. - Setelah masa tenggang (misalnya 14 hari): job terjadwal hard delete catatan milik akun itu
dalam batch kecil (misalnya 1.000 baris per transaksi) supaya tidak mengunci tabel 50 juta
baris. Jangan satu
CASCADEraksasa. - Turunan: job yang sama mengirim event penghapusan ke indeks pencarian dan menghapus key cache pengguna. Job mencatat hasil dan mengulang kalau ada yang gagal, karena penghapusan di indeks pencarian bisa tertinggal.
- Verifikasi: query pemeriksaan memastikan tidak ada catatan, entri indeks, atau key cache tersisa untuk akun itu.
Yang tersisa: data di backup tetap ada sampai backup terakhir yang memuatnya kedaluwarsa, maksimal sekitar 30 hari setelah hard delete. Itu harus dinyatakan jelas di kebijakan privasi. Kalau backup dipulihkan dalam rentang itu, daftar akun yang sudah dihapus harus diterapkan ulang sebelum layanan dibuka.
Jawaban yang bagus memisahkan penghapusan logis dari fisik, memecah hard delete dalam batch, dan jujur soal backup.
Terkait
- M01.02 Jelaskan beban kerja membantu menghitung laju pertumbuhan data seperti 20 GB per hari di atas.
- M04.05 membahas migrasi skema yang dibutuhkan saat menambah kolom
deleted_atatau partisi. - M06 Caching bahas kedaluwarsa dan invalidasi salinan di cache.
- M07 Partisi dan penempatan data bahas partisi pada skala lebih besar.
- Rancangan D03 dan Lab L04 menyentuh pertumbuhan data dan retensi.
Catatan
- Asumsi: angka retensi hanyalah contoh. Kewajiban hukum yang sebenarnya bergantung pada yurisdiksi dan jenis bisnis, dan harus dikonfirmasi dengan pihak yang berwenang.
- Yang nggak dibahas: kebijakan privasi dan regulasi tertentu, enkripsi dan crypto-shredding, serta desain backup dan pemulihan bencana.
- Terakhir ditinjau: 26 Oktober 2026.