Tunas Akara
Kembali ke Blog

pg_dump Bukan Backup Sebelum Pernah Di-restore

oleh RayhanDiperbarui 6 menit baca
postgresqlbackupdisaster-recoverydata-engineering
pg_dump Bukan Backup Sebelum Pernah Di-restore

pg_dump Bukan Backup Sebelum Pernah Di-restore

Ban serep yang belum pernah dipasang bukan ban serep. Itu cuma dugaan bahwa bannya masih bisa dipompa. Kebanyakan sistem production yang saya audit punya cerita backup yang sama persis: cron job menjalankan pg_dump tiap malam, file-nya mendarat di suatu tempat dengan tanggal di namanya, dan semua orang merasa aman.

Perasaan aman itulah masalahnya. Direktori penuh file dump bertanggal membuktikan tepat satu hal: ada proses yang menulis file. Apakah file itu bisa menjadi database yang berfungsi lagi adalah pertanyaan terpisah — dan satu-satunya pertanyaan yang penting.

Dump yang belum pernah di-restore itu hipotesis

Uji restore adalah backup yang sesungguhnya. File dump cuma bahan mentahnya. Mode gagal yang ia tangkap semuanya tak terlihat dari luar: dump terpotong karena disk penuh atau proses ter-kill, pg_restore beda versi, role dan extension yang cuma ada di server lama, atau job yang setia men-dump database yang salah selama berbulan-bulan. Semuanya tetap menghasilkan file dengan ukuran masuk akal dan tanggal terbaru.

Solusinya job terjadwal, bukan dokumen kebijakan: restore dump terbaru ke instance scratch, jalankan pengecekan migrasi aplikasi, hitung row di tabel-tabel penting, dan eksekusi beberapa query yang hasilnya sudah diketahui. Kalau ada langkah yang gagal, itu alert dengan severity setara production down — karena artinya production sedang tidak punya backup.

Ada bonus kedua yang sering kelewat. Job restore itu adalah latihan disaster-nya. Hari sesuatu benar-benar rusak, yang dijalankan adalah script yang sudah sukses ratusan kali, bukan mengarang runbook jam 3 pagi.

Database saja bukan seluruh data

Ini celah yang paling sering menggigit. Sistem nyata menyimpan row dan file: PDF invoice, foto tamu, lampiran insiden, dokumen scan. Row memegang path; object storage memegang byte-nya.

Rezim backup yang hanya mencakup PostgreSQL menghasilkan restore berupa database penuh pointer ke file yang sudah tidak ada. Restore-nya sukses di atas kertas. Kenyataannya, data hilang.

File yang dirujuk row database adalah bagian dari data, titik. Cakupan backup harus memasukkan object storage, di-mirror atau di-versioning dengan jadwal dan retensi yang sama dengan database, dan uji restore harus memverifikasi kedua sisi bersamaan. Sistem seperti platform manajemen hotel menghasilkan media terus-menerus. Foto status kamar itu bukti, bukan hiasan — kehilangannya masalah bisnis, meski semua row selamat.

Retensi dan target waktu restore

Dua angka mendefinisikan rezim backup. Keduanya harus keputusan, bukan kebetulan:

  • Berapa banyak data yang rela hilang? Jarak antar backup adalah data yang secara implisit disetujui untuk hilang. Dump malam berarti sampai 24 jam raib. Kalau itu tidak bisa diterima, yang dibutuhkan adalah WAL archiving — mengarsipkan write-ahead log, catatan berjalan semua perubahan database — dan point-in-time recovery, bukan dump yang lebih sering.
  • Berapa lama rela down? Ukur restore-nya, jangan diperkirakan. Restore logical — menjalankan ulang ekspor isi database berbentuk perintah SQL — pada database besar makan berjam-jam; rebuild index yang mendominasi, dan biasanya orang baru tahu ini justru saat outage. Kalau waktu terukur melebihi target, pindah ke physical backup, salinan file mentah database — untuk itulah tool seperti pgBackRest ada.

Retensi menjawab pertanyaan berbeda: seberapa jauh Anda bisa mundur saat korupsi data ketahuan terlambat? Deploy buruk yang diam-diam merusak data bisa tak terdeteksi berminggu-minggu. Bentuk praktisnya: rolling window harian plus snapshot mingguan dan bulanan yang hidup lebih lama.

Verifikasi sambungannya terus-menerus

Di antara dua bencana, data bergeser. Row terhapus tanpa file-nya, file terupload tanpa row-nya, script cleanup kebablasan. Job rekonsiliasi periodik menjaga kedua penyimpanan tetap jujur:

Loading diagram…

Job-nya membosankan: daftar apa yang dirujuk row, daftar isi storage, diff kedua himpunan. Job ini mengubah korupsi senyap menjadi tiket, bukan kejutan. Jalankan mingguan; alert pada setiap pertumbuhan himpunan "hilang".

Backup hal-hal yang tak bisa diciptakan ulang

Urutan prioritas lahir dari satu pertanyaan: kalau server ini lenyap, apa yang tidak bisa kita buat ulang? Kode ada di git. Container di-rebuild dari Dockerfile. Package tinggal install ulang.

Yang tidak bisa diciptakan ulang: database, file yang diupload, sertifikat TLS dan secret, plus tumpukan keputusan konfigurasi kecil yang menumpuk bertahun-tahun. Himpunan tak tergantikan itulah cakupan backup — dan selalu lebih besar dari sekadar PostgreSQL.

Resepnya biasa saja. Satu instance scratch, dua job terjadwal, dan disiplin memperlakukan uji restore yang gagal sebagai insiden production. Tim yang menjalankannya tidak pernah punya cerita backup yang seru — dan memang itu tujuannya.

Saat Anda benar-benar restore ke environment baru, detail yang selama ini dianggap remeh cepat muncul lagi. Konfigurasi timezone contoh klasiknya, itu sebabnya saya selalu memasukkan pengelompokan timestamp lintas timezone ke daftar query uji restore.

Artikel Terkait

Mau bangun hal serupa?

Jasa Pengembangan Backend IoT & Integrasi Multi-Protokol

Backend yang menyerap telemetri perangkat lintas MQTT, WebSocket, Modbus, dan BLE, lalu menyatukannya jadi dashboard real-time yang andal.

Lihat cara saya bisa bantu