Masalah replikasi jarang memperkenalkan diri di server — ia muncul di sisi aplikasi: data yang baru ditulis tidak terbaca, write yang menggantung menunggu mayoritas, atau primary yang berganti tanpa kabar. Untuk bisa mengenali keadaan abnormal, kita perlu dulu hafal keadaan normalnya. Replica set satu anggota rs0 kita adalah baseline yang sempurna untuk itu: seluruh field diagnosis rs.status() dan rs.conf() bisa dibaca tanpa derau multi-node, lalu gejala-gejala klaster besar kita petakan di atasnya.

Peta materi Chapter ini:

  • Baseline sehat: membaca rs.status() dan rs.conf() secara selektif.
  • Galeri state multi-node: STARTUP2, RECOVERING, ROLLBACK, lag, dan election berulang.
  • Gejala yang terlihat dari aplikasi: baca basi, write concern timeout, failover.
  • Tabel rujukan gejala-tindakan dengan rujukan ke Section Replication.

Baseline Sehat: Seperti Apa Normalnya #

Dua perintah membuka setiap sesi diagnosis replikasi. Yang pertama, rs.status(), kita padatkan ke field-field yang benar-benar dipakai saat membandingkan anggota:

js
const st = rs.status()
({
  set: st.set,
  myState: st.myState,
  term: st.term,
  anggota: st.members.map(m => ({
    name: m.name, state: m.stateStr, health: m.health, uptime: m.uptime,
    optimeDate: m.optimeDate,
    lastHeartbeatMessage: m.lastHeartbeatMessage
  }))
})

Output yang Dihasilkan:

text
{
  set: 'rs0',
  myState: 1,
  term: Long('8'),
  anggota: [
    {
      name: '127.0.0.1:27017',
      state: 'PRIMARY',
      health: 1,
      uptime: 37168,
      optimeDate: ISODate('2026-10-17T23:24:48.000Z'),
      lastHeartbeatMessage: ''
    }
  ]
}

Cara bacanya berurutan: health: 0 berarti heartbeat ke anggota itu gagal — seluruh field lainnya untuk anggota tersebut menjadi tidak bisa dipercaya. state adalah posisi anggota saat ini (PRIMARY, SECONDARY, atau state transisi yang kita bahas sebentar lagi). optimeDate adalah waktu write terakhir yang diterapkan anggota — pada cluster multi-node, selisih optimeDate antar secondary dan primary adalah definisi paling praktis dari replication lag. Terakhir, lastHeartbeatMessage berisi catatan diagnostic dari sudut pandang node yang kita hubungi; string kosong pada contoh kita wajar karena node tunggal tidak mengirim heartbeat ke siapa pun. Dua nilai lain — uptime dan optimeDate — tentu berbeda di setiap eksekusi karena keduanya berjalan seiring waktu.

Perintah kedua memeriksa konfigurasi — sering kali penyebab masalah ada di sini, bukan di server:

js
const conf = rs.conf()
({
  set: conf._id,
  protocolVersion: conf.protocolVersion,
  writeConcernMajorityJournalDefault: conf.writeConcernMajorityJournalDefault,
  anggota: conf.members.map(m => ({ host: m.host, priority: m.priority, votes: m.votes, hidden: m.hidden }))
})

Output yang Dihasilkan:

text
{
  set: 'rs0',
  protocolVersion: Long('1'),
  writeConcernMajorityJournalDefault: true,
  anggota: [ { host: '127.0.0.1:27017', priority: 1, votes: 1, hidden: false } ]
}

Empat field per anggota menjawab empat pertanyaan diagnosis: priority menentukan siapa berhak merebut jabatan primary (anggota lambat sebaiknya diberi priority rendah), votes menentukan siapa yang dihitung dalam mayoritas election dan write concern, hidden mengecualikan anggota dari pemilihan primary sekaligus dari read preference biasa, dan writeConcernMajorityJournalDefault mengatur jaminan default write mayoritas. Mengubah nilai-nilai ini lewat rs.reconfig() adalah operasi administratif — pola amannya dibahas di Section Replication.

Galeri State Multi-Node #

Pada cluster nyata, kolom state di rs.status() adalah papan pengumuman. State-state yang paling sering memicu pertanyaan:

  • STARTUP2 — anggota sedang menjalankan initial sync: menyalin seluruh data dari anggota sehat. Ini state yang benar untuk anggota baru; yang perlu diperiksa hanyalah progresnya. Bila anggota diam di STARTUP2 terlalu lama, tersangka utamanya adalah jaringan lambat atau disk yang tidak sanggup menulis secepat sumber membaca.
  • RECOVERING — anggota mengejar ketertinggalan internal dan menolak melayani baca sampai selesai. Selama posisinya terus maju (pantau optimeDate), tindakan terbaik adalah menunggu; mekanisme dan batasannya dirinci di Chapter Troubleshooting Replica Set.
  • ROLLBACK — mantan primary yang kembali dengan write yang tidak sempat direplikasi mayoritas. Data yang digulung tetap disimpan untuk ditelaah operator sebelum diputuskan dimasukkan ulang atau tidak.
  • Election berulang — primary silih berganti dalam waktu singkat, terlihat dari term yang melompat cepat. Hampir selalu masalah infrastruktur (jaringan, spesifikasi anggota yang timpang), bukan parameter MongoDB.

Satu gejala administratif yang berbeda: bila rs.status() sendiri menolak dijalankan dengan galat NotYetInitialized (kode 94), node itu belum pernah menerima konfigurasi replica set — periksa apakah mongod dijalankan dengan --replSet dan apakah rs.initiate() sudah pernah dipanggil.

Gejala dari Sisi Aplikasi #

Tiga keluhan pengguna yang akarnya ada di replikasi. Pertama, baca basi: aplikasi membaca dari secondary yang tertinggal sehingga data yang baru ditulis “hilang sesaat” — atasi dengan readPreference=primary untuk alur baca-tulis-kirim-ulang, atau maxStalenessSeconds untuk batas ketinggalan. Kedua, write menggantung: write concern w: "majority" menunggu pengakuan mayoritas; bila cukup banyak anggota voting tidak sehat, mayoritas tak tercapai dan operasi berhenti sampai timeout — pulihkan anggotanya, atau sementara turunkan write concern dengan kesadaran penuh atas risikonya. Ketiga, galat NotWritablePrimary sesaat saat failover: driver modern mencoba ulang write secara otomatis (retryable writes), sehingga keluhan ini biasanya hanya muncul pada driver lama atau retry yang dimatikan.

GejalaPembacaan pertamaTindakan
Anggota diam di STARTUP2Progres initial sync, beban jaringan/diskTunggu bila maju; audit jalur sync bila diam
Lag membesar (selisih optimeDate)rs.status() per anggotaIkuti tabel mitigasi di Chapter Replication Lag
Anggota RECOVERING lamaJendela oplog vs lama downtimeTunggu bila maju; initial sync ulang bila mentok
term melompat berulangRiwayat electionAudit jaringan dan spesifikasi; setel priority
Write w: "majority" timeoutAnggota voting yang tidak sehatPulihkan anggota; cek jumlah voting genap
Baca basi dari secondaryreadPreference aplikasiprimary untuk alur kritis; maxStalenessSeconds
rs.status() galat kode 94Node tanpa konfigurasi replSetPastikan --replSet dan rs.initiate()

Rangkuman #

  • Baseline sehat dibaca dari dua perintah: rs.status() (health, state, lag, term) dan rs.conf() (priority, votes, hidden).
  • STARTUP2 adalah initial sync yang berjalan normal; RECOVERING dan ROLLBACK dibedakan oleh arah pemulihannya.
  • Gejala replikasi sering muncul di aplikasi dulu: baca basi, write concern timeout, dan failover singkat.
  • NotYetInitialized kode 94 berarti masalah konfigurasi server, bukan kesehatan cluster.