Snapshot terakhir diambil Sabtu dini hari; Senin pukul 10.32 sebuah skrip salah menghapus collection transaksi. Memulihkan dari snapshot berarti kehilangan dua hari aktivitas — padahal data yang benar sempat hidup sampai pukul 10.31. Point-in-time recovery (PITR) menjawab skenario ini: snapshot sebagai titik dasar, oplog sebagai rekaman putar ulang, dipulihkan tepat sampai detik sebelum masalah terjadi. Chapter ini membahas konsepnya, batas jangkauannya yang ditentukan oplog, dan prosedurnya — dengan pemeriksaan oplog yang dijalankan nyata pada replica set latihan kita.
Peta materi Chapter ini:
- Konsep dasar: snapshot sebagai dasar, oplog sebagai rekaman maju.
- Oplog, jendela waktunya, dan artinya bagi seberapa jauh kita bisa mundur.
- Prosedur
mongorestore --oplogReplay --oplogLimitdan PIT di Atlas.
Mundur ke Titik Waktu #
PITR bekerja seperti sistem jurnal pada database relasional: sebuah snapshot penuh memberi keadaan dasar, lalu log operasi diputar maju — bukan mundur — sampai titik tujuan. Perlu digarisbawahi arah kerjanya: kita tidak “membatalkan” kesalahan, melainkan membangun ulang seluruh perjalanan data lalu berhenti tepat sebelum momen masalah. Rumusnya selalu dua komponen:
Syaratnya satu: keduanya harus berasal dari sumber yang sama dan berkesinambungan — kita butuh semua entri oplog sejak snapshot diambil sampai titik tujuan. Karena itu PITR selalu berpasangan dengan strategi backup yang menyimpan oplog secara berkelanjutan (layanan backup terkelola) atau mengekspornya berkala.
Oplog dan Jendela Waktunya #
Oplog (operation log) adalah capped collection local.oplog.rs yang merekam setiap operasi tulisan pada replica set — inilah media replikasi antar-node sekaligus bahan baku PITR. Setiap entri membawa kode operasi, namespace, muatan operasi, dan timestamp BSON yang presisi ke urutan operasi dalam satu detik. Mari kita lihat entri asli: sisipkan satu document lalu baca entri oplog terbaru untuk namespace itu:
use latihan_backup
db.dropDatabase()
db.penjualan.insertOne({ _id: 104, bukuId: 3, jumlah: 2 })
db.getSiblingDB("local").oplog.rs.find(
{ ns: "latihan_backup.penjualan" },
{ op: 1, ns: 1, ts: 1, o: 1 }
).sort({ $natural: -1 }).limit(1)Output yang Dihasilkan:
switched to db latihan_backup
{ ok: 1, dropped: 'latihan_backup' }
{ acknowledged: true, insertedId: 104 }
[
{
op: 'i',
ns: 'latihan_backup.penjualan',
o: { _id: 104, bukuId: 3, jumlah: 2 },
ts: Timestamp({ t: 1792265232, i: 5 })
}
]Satu baris oplog memuat segalanya yang diperlukan untuk memutar ulang tulisan tersebut: op: 'i' berarti insert, ns menunjuk collection, o menyimpan document lengkapnya, dan ts berupa Timestamp dengan dua bagian — detik sejak epoch (t) dan nomor urut operasi dalam detik itu (i). Format dua bagian inilah yang nanti kita pakai sebagai batas replay. Karena oplog adalah capped collection, entri lama terdorong keluar begitu penuh — dan di sinilah letak batas PITR: ukuran oplog menentukan seberapa jauh ke belakang titik dasar snapshot boleh berada. Jendela waktunya bisa kita tanyakan langsung ke replica set:
rs.printReplicationInfo()Output yang Dihasilkan:
actual oplog size
'990 MB'
---
configured oplog size
'990 MB'
---
log length start to end
'23980 secs (6.66 hrs)'
---
oplog first event time
'Sat Oct 17 2026 12:47:32 GMT+0000 (Coordinated Universal Time)'
---
oplog last event time
'Sat Oct 17 2026 19:27:12 GMT+0000 (Coordinated Universal Time)'
---
now
'Sat Oct 17 2026 19:27:12 GMT+0000 (Coordinated Universal Time)'Enam baris ini adalah “spedometer” PITR kita (angka jendela dan waktu akan berbeda di setiap eksekusi — yang stabil adalah strukturnya). Replica set latihan memiliki oplog 990 MB yang saat ini menampung 6,66 jam sejarah tulisan — artinya snapshot yang lebih lawas dari itu tidak bisa diperpanjang lagi lewat replay. Pada deployment sungguhan, ukuran oplog default WiredTiger adalah 5% ruang disk kosong (dibatasi minimum 990 MB dan maksimum 50 GB), dan beban tulisan yang tinggi memperpendek jendela waktunya karena entri lebih cepat terdorong keluar. Memperpanjang jendela berarti memperbesar oplog — bisa sejak awal lewat replication.oplogSizeMB, atau tanpa restart lewat perintah replSetResizeOplog.
Prosedur Snapshot + Replay #
Dengan konsepnya jelas, prosedur PITR self-managed berjalan dalam empat langkah:
- Pilih snapshot terakhir yang diambil sebelum titik tujuan — titik dasar pemulihan.
- Siapkan berkas oplog yang mencakup rentang snapshot sampai titik tujuan (misalnya hasil tangkapan berkala atas
local.oplog.rs, atauoplog.bsondari dump--oplog). - Restore snapshot, lalu putar ulang oplog dengan batas waktu:
# replay oplog dan BERHENTI sebelum entri ber-timestamp >= batas
# format batas: <detik-epoch>:<nomor-urut-dalam-detik>
mongorestore --uri="mongodb://127.0.0.1:27017/?directConnection=true" \
--oplogReplay --oplogLimit="1792265232:5" --archive=dump_konsisten.archiveOpsi --oplogLimit mencegah mongorestore menerapkan entri yang sama baru atau lebih baru dari timestamp batas — contoh di atas memakai timestamp entri insert dari blok sebelumnya, sehingga replay berhenti tepat sebelum operasi itu diterapkan. Untuk berhenti tepat sebelum insiden pukul 10.32, batasnya adalah timestamp entri terakhir yang masih benar. Opsi ini wajib dipasangkan dengan --oplogReplay, dan perlu dicatat: sharded cluster tidak mendukung --oplogReplay.
- Verifikasi hasil restore — jumlah document, query sampel, agregat pembanding — persis seperti prosedur di chapter Restore Testing.
Satu keterbatasan mendasar perlu dipahami: replay hanya bisa maju. Operasi yang salah di tengah jalan tetap akan diputar ulang bila berada sebelum titik henti; kita tidak bisa “melompati” satu entri oplog di tengah. Karena itu titik henti harus dipilih cermat — dan di sinilah timestamp oplog yang presisi ke urutan operasi menunjukkan nilainya.
PIT di Atlas #
Pada MongoDB Atlas, seluruh mekanik di atas berjalan di balik layar lewat Continuous Cloud Backup: oplog di-streaming ke object storage, dan titik dasarnya adalah snapshot terjadwal. Saat restore, kita cukup memilih Point in Time Restore lalu memasukkan titik tujuan lewat tab Date & Time (granularitas satu menit) atau Oplog Timestamp (granularitas satu detik — format yang sama dengan --oplogLimit). Jendela waktunya mengikuti kebijakan restore window, dan satu-satunya celah yang tidak bisa dituju adalah rentang restore yang sedang berjalan hingga snapshot pertama selepasnya.
Rangkuman #
- PITR = snapshot terakhir sebelum titik tujuan + replay oplog maju sampai sebelum momen masalah; arah kerjanya selalu maju.
- Oplog (
local.oplog.rs) merekam tiap tulisan denganTimestampberformat detik-epoch + nomor urut — format yang sama dipakai--oplogLimit. - Jendela oplog (
rs.printReplicationInfo()) menentukan seberapa jauh ke belakang snapshot dasar boleh berada; ukuran default 5% disk kosong (990 MB - 50 GB) dan beban tulisan tinggi memperpendeknya. - Prosedur inti: restore snapshot →
mongorestore --oplogReplay --oplogLimit=<t>:<i>→ verifikasi; sharded cluster tidak mendukung--oplogReplay. - Atlas menyediakan PIT yang setara lewat Continuous Cloud Backup dengan pilihan titik waktu bergranularitas menit atau detik.