Episode ini menguji recovery dalam tiga skenario nyata: cluster korup yang dipulihkan ke backup terakhir plus WAL, hilangnya seluruh direktori data yang mengharuskan rebuild dari nol, dan pembuatan instance clone atau standby baru dari backup. Diakhiri latihan simulasi crash dan PITR ke waktu spesifik.

Di episode 8 kita menguasai perintah restore. Sekarang tibalah ujian sesungguhnya: skenario recovery dalam situasi nyata. Karena bencana tidak pernah datang sebagai kasus yang rapi — cluster korup di tengah jam sibuk, direktori data hilang setelah disk rusak, atau kebutuhan mendadak untuk instance kedua. Di episode 9 kita melatih tiga skenario: corrupt, lost, dan clone, lalu menutupnya dengan simulasi crash dan PITR yang bisa kalian ulangi sendiri.
Ini mengapa DBA yang baik berbeda dari DBA yang "cukup": bukan karena bisa menjalankan restore, tetapi karena sudah melatih skenario bencana sebelum bencana datang.
PostgreSQL tidak bisa start, atau memunculkan error korupsi seperti invalid page in block atau could not read block. Server masih ada, data masih ada, tetapi rusak.
Karena data rusak, percaya pada file lokal tidak masuk akal — kita timpa dengan backup memakai --delta agar hanya file yang berbeda yang diganti:
sudo systemctl stop postgresql
sudo -u postgres pgbackrest --stanza=main --delta restore
sudo systemctl start postgresqlCatatan penting: jika kerusakan berasal dari disk fisik (bad sector, filesystem korup), jangan restore ke disk yang sama — itu hanya menyalin masalah. Pindahkan PGDATA ke disk sehat, lalu restore.
Note
--delta di sini adalah pilihan tepat karena sisa file yang tidak korup ikut dipakai, mempercepat recovery. Tetapi jika kalian mencurigai korupsi menyebar, lebih aman restore penuh ke direktori baru (Skenario 2) daripada mencampur file lokal yang mungkin rusak.
/var/lib/postgresql/16/main hilang atau tidak terbaca — disk mati, format tak sengaja, atau instance dihapus. Tidak ada yang bisa diselamatkan dari lokal; semua harus di-rebuild dari repository.
sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/16/main
sudo -u postgres pgbackrest --stanza=main --type=immediate restore
sudo systemctl start postgresqlPerhatikan: restore menciptakan kembali seluruh PGDATA termasuk postgresql.conf (versi yang di-backup) dan file PG_VERSION. Jika parameter server diubah setelah backup terakhir, kalian perlu menyelaraskannya kembali — postgresql.auto.conf dan file konfigurasi lain di luar PGDATA tidak ikut di-backup.
Setelah restore, cek parameter penting yang mungkin berbeda dari ekspektasi:
psql -U postgres -c "SHOW archive_mode; SHOW listen_addresses;"Sesuaikan postgresql.conf/postgresql.auto.conf bila perlu, lalu restart sekali lagi. Prosedur ini adalah full recovery — kehilangan seluruh data dir tidak lagi berarti kehilangan data.
Butuh instance kedua: environment staging yang mendekati produksi, analitik tanpa membebani primary, atau standby baru untuk HA (dibahas lebih dalam di episode 18). Semua bisa di-clone dari backup yang sama — tanpa menyentuh primary.
Restore ke direktori terpisah dengan --delta memakai PGDATA kosong:
sudo mkdir -p /var/lib/postgresql/staging
sudo chown postgres:postgres /var/lib/postgresql/staging
sudo -u postgres pgbackrest --stanza=main --delta --pg1-path=/var/lib/postgresql/staging restore--pg1-path mengarahkan restore ke direktori yang berbeda dari config. Setelah restore, sesuaikan port dan socket di postgresql.conf clone agar tidak bentrok, lalu start sebagai instance terpisah:
sudo -u postgres /usr/lib/postgresql/16/bin/pg_ctl -D /var/lib/postgresql/staging startTip
Ini pola yang dipakai berulang-ulang di production: staging yang selalu "fresh" dari backup terakhir, analitik offload, atau bypass pg_dump yang lambat. Memahami clone dari backup berarti memahami bahwa backup bukan hanya untuk bencana — ia adalah bahan baku lingkungan baru.
Mari gabungkan semuanya dalam satu latihan yang bisa kalian ulang kapan pun.
CREATE TABLE uji_pit (id int primary key, ts timestamptz default now());
INSERT INTO uji_pit (id) SELECT generate_series(1,100);
SELECT pg_create_restore_point('sebelum-crash');INSERT INTO uji_pit (id) SELECT generate_series(101,200);Lalu hentikan cluster secara paksa — simulasi crash tanpa shutdown bersih:
sudo systemctl stop postgresqlPulihkan ke restore point sebelum-crash (hanya 100 row yang ada saat itu):
sudo -u postgres pgbackrest --stanza=main --type=name 'sebelum-crash' --target-action=pause restore
sudo systemctl start postgresqlSELECT count(*) FROM uji_pit; -- harus 100, bukan 200Jika hasilnya 100, PITR bekerja sempurna. Ulangi latihan dengan --type=time atau --type=lsn untuk melatih varian lain.
Warning
Simulasi crash tanpa backup yang teruji adalah alasan utama kegagalan recovery di dunia nyata. Jadikan latihan ini rutinitas bulanan (episode 16 membahas drill terjadwal) — dan selalu uji di instance terpisah, bukan di production langsung.
Inti yang harus dibawa pulang:
--delta restore, restart — pindah ke disk sehat jika penyebabnya fisik.restore --type=immediate, lalu selaraskan konfigurasi.--pg1-path untuk staging, analitik, atau standby.Di episode 10 selanjutnya kita akan menjadikan semua ini otomatis: scheduling & retention policy — menjadwalkan full mingguan dan differential harian lewat cron atau systemd timer, memahami peran WAL archiving yang berjalan real-time, serta menentukan nilai retention berdasarkan RPO dan RTO bisnis kalian. Backup yang andal harusnya tidak bergantung pada ingatan manusia!