Cara Backup Database PostgreSQL Otomatis
Ada satu pertanyaan yang memisahkan sistem yang aman dari yang hanya merasa aman: kapan terakhir kali Anda me-restore backup? Kalau jawabannya "belum pernah", maka status backup Anda sesungguhnya adalah "belum tahu". Backup yang tidak pernah diuji pulih punya kebiasaan buruk gagal justru pada malam ia dibutuhkan. Tutorial ini membangun rantai lengkapnya untuk PostgreSQL: dump harian, rotasi, salinan keluar server, dan — bagian yang membedakan — ritual uji restore yang membuat semuanya bisa dipercaya.
Dua jenis kehilangan data yang harus diantisipasi
Rancangan backup yang baik melindungi dari dua musuh yang berbeda. Bencana mesin: disk mati, VPS hilang, server disusupi — obatnya salinan di tempat lain. Kesalahan manusia dan aplikasi: DELETE tanpa WHERE, migrasi yang salah, bug yang mengotori data selama tiga hari sebelum ketahuan — obatnya riwayat beberapa versi, karena backup semalam yang menimpa backup kemarin ikut menyimpan kesalahannya. Kombinasi keduanya menentukan bentuk akhir kita: dump harian, disimpan berlapis hari, dengan salinan off-server.
Langkah 1: Kenali pg_dump dan formatnya
pg_dump memotret satu database menjadi file yang bisa diputar ulang. Dua format yang relevan: format plain (SQL teks biasa — bisa dibaca mata, enak untuk database kecil) dan format custom (-Fc, terkompresi dan mendukung restore selektif — pilihan yang tepat begitu database mulai berarti):
pg_dump -Fc -U postgres tokodb -f tokodb.dump
Pasangannya untuk memulihkan: pg_restore. Dan satu fakta yang menyenangkan: pg_dump aman dijalankan saat database sedang dipakai — ia memotret keadaan yang konsisten tanpa mengunci aplikasi Anda.
Langkah 2: Buat skrip backup harian
Simpan sebagai /opt/backup/pg-backup.sh:
#!/bin/bash
set -euo pipefail
DB="tokodb"
DIR="/var/backups/postgres"
KEEP_DAYS=14
STAMP=$(date +%Y%m%d-%H%M%S)
mkdir -p "$DIR"
pg_dump -Fc "$DB" -f "$DIR/$DB-$STAMP.dump"
# rotasi: buang yang lebih tua dari KEEP_DAYS
find "$DIR" -name "$DB-*.dump" -mtime +$KEEP_DAYS -delete
# verifikasi minimal: file ada dan tidak kosong
test -s "$DIR/$DB-$STAMP.dump"
echo "OK $STAMP $(du -h "$DIR/$DB-$STAMP.dump" | cut -f1)"
Tiga baris yang bekerja lebih keras dari kelihatannya: set -euo pipefail membuat skrip berhenti bersuara saat ada langkah gagal (bukan lanjut pura-pura sukses), rotasi find -mtime menjaga disk tidak penuh diam-diam, dan test -s menolak menganggap file kosong sebagai backup. Beri izin eksekusi (chmod +x) dan jalankan sekali manual sampai keluar baris OK.
Langkah 3: Jadwalkan dengan cron
Di crontab user yang punya akses database (crontab -e):
15 2 * * * /opt/backup/pg-backup.sh >> /var/log/pg-backup.log 2>&1
Jam 02:15 setiap malam, dengan seluruh keluaran tercatat ke log. Besok paginya, periksa dua hal: file dump baru ada di folder, dan baris OK ada di log. Lalu pasang kabar kegagalan — pilihan paling sederhana: satu workflow n8n terjadwal yang mengecek umur file backup terbaru dan berteriak ke Telegram kalau backup terakhir lebih tua dari 26 jam. Backup yang gagal dalam sunyi selama sebulan sama saja tidak ada.
Langkah 4: Kirim salinan keluar server
Backup yang tidur di server yang sama dengan database-nya gugur bersama server itu. Tambahkan di akhir skrip pengiriman ke tempat lain — object storage (S3 atau yang sejenis) via aws s3 cp atau rclone, atau minimal rsync ke mesin lain:
rclone copy "$DIR/$DB-$STAMP.dump" remote-backup:tokodb/
Dua catatan keamanan: dump berisi seluruh data Anda, jadi tujuan penyimpanannya harus terkunci sekelas database-nya (bucket privat, akses terbatas), dan kredensial pengiriman di server sebaiknya hanya punya izin menulis — sehingga penyusup yang menguasai server tidak bisa ikut menghapus sejarah backup Anda.
Langkah 5: Uji restore secara berkala
Inilah ritualnya — sebulan sekali, tiga puluh menit, di mesin lain atau container sementara:
createdb tokodb_uji
pg_restore -d tokodb_uji tokodb-TERBARU.dump
psql tokodb_uji -c "SELECT COUNT(*) FROM penjualan;"
dropdb tokodb_uji
Restore jalan, tabel utama berisi angka yang masuk akal, selesai. Ritual ini mengubah kalimat Anda dari "harusnya bisa dipulihkan" menjadi "bulan lalu saya memulihkannya dalam sekian menit" — dan angka sekian menit itu sendiri berharga: itulah perkiraan jujur berapa lama bisnis Anda berhenti saat insiden sungguhan. Kalau angkanya tidak bisa diterima, Anda tahu sekarang, bukan nanti.
Rantai yang sama berlaku untuk semua yang berharga di server Anda — workflow n8n punya versinya sendiri. Dan kalau Anda lebih tenang saat seluruh lapisan ini — dari desain database sampai disiplin backup-nya — dipegang tim yang mengerjakannya tiap hari, layanan software Clovertechno mencakup persis itu.
Clovertechno