Prompt dan Peran yang Berlaku
Sebuah primary PostgreSQL mengalirkan perubahan pesanan ke warehouse dan layanan pencarian melalui replikasi logis. Primary dapat mengalami kegagalan saat konsumen tertinggal. Rancang failover terencana dan tidak terencana, jelaskan cara memverifikasi bahwa logical slot pada standby dapat mengambil alih, cara menghindari rentang LSN yang duplikat atau terlewat, dan cara memulihkan sistem ketika kontinuitas slot tidak dapat dibuktikan.
Topik ini cocok untuk wawancara backend, platform basis data, infrastruktur data, dan SRE. Bedakan subscriber PostgreSQL dari konsumen non-PostgreSQL seperti Debezium: tipe pertama dapat menggunakan pengaturan failover bawaan, sedangkan tipe kedua tetap memerlukan bukti independen di seluruh status konektor, slot, dan rekonsiliasi. "Standby telah tersinkronisasi" tidak membuktikan bahwa setiap konsumen logis dapat melanjutkan proses secara mulus.
Hal yang Diuji oleh Pewawancara
Jawaban yang kuat menyatakan invarian yang dapat diverifikasi: aliran logis pada primary baru tidak boleh bergerak mundur; konsumen melanjutkan dari posisi yang terkonfirmasi, dengan duplikat diizinkan tetapi celah data tanpa peringatan (silent gaps) dilarang; dan failover dikendalikan oleh sinkronisasi slot serta kemajuan konsumen. Kandidat harus memisahkan failover terencana—di mana penulisan dapat dijeda dan konsumen dapat dikosongkan (drained)—dari kegagalan tidak terencana, di mana cadangan (backup), snapshot penuh, dan rekonsiliasi mungkin menjadi satu-satunya perbaikan yang aman. Mengarahkan DNS ke standby tidak menyelesaikan masalah slot, retensi WAL, atau konsumen non-PostgreSQL.
Pertanyaan untuk Diklarifikasi Sebelum Menjawab
- Apa saja konsumennya? Subscriber PostgreSQL, Debezium, pemuat warehouse, dan custom decoder memiliki antarmuka kemajuan dan pemulihan yang berbeda.
- Apakah duplikat dapat diterima? Pengiriman at-least-once biasanya dapat diterima jika target melakukan deduplikasi berdasarkan LSN, ID transaksi, atau kunci idempoten; skrip tidak dapat menjamin exactly-once hanya dengan pernyataan.
- Apakah ini failover terencana atau bencana? Peralihan terencana dapat menjeda penulisan dan menunggu standby; setelah kegagalan tidak terencana, LSN terakhir yang di-commit dan dikonfirmasi konsumen mungkin tidak diketahui.
- Apakah batasan transaksi lintas tabel penting? Jika downstream memerlukan tampilan pesanan dan detail pesanan (order-line) yang atomik, sebarkan batasan transaksi daripada membandingkan LSN satu baris.
- Berapa banyak WAL yang dapat dipertahankan? Slot yang tertinggal menghalangi pembersihan WAL, berisiko menghabiskan disk pada primary; slot yang tidak valid dapat menciptakan celah yang tidak dapat dipulihkan.
- Bisakah konsumen dibangun kembali dari snapshot? Jika kontinuitas tidak dapat dibuktikan, siapkan snapshot penuh, rekonsiliasi versi, dan rencana degradasi atau pemeliharaan.
Kerangka Jawaban 30 Detik
"Saya akan menegaskan invarian secara eksplisit: posisi slot primary baru mencakup posisi terkonfirmasi terakhir konsumen, dan LSN sumber yang dipulihkan bergerak secara monotonik. Peristiwa duplikat boleh diputar ulang, tetapi tidak boleh ada rentang yang terlewat tanpa peringatan. Untuk failover terencana, jeda atau batasi (throttle) penulisan, verifikasi bahwa failover slot disinkronkan ke standby dan standby berada di depan konsumen, hentikan konektor setelah mencatat LSN yang aman, promosikan standby, dan lanjutkan konsumen.
PostgreSQL 17 dapat menyinkronkan failover slot secara asinkron ke standby, tetapi peralihan harus memeriksa bahwa setiap slot ada, disinkronkan, non-sementara, dan tidak memiliki alasan pembatalan. Debezium dan konsumen non-PostgreSQL lainnya harus memverifikasi slot dan LSN mereka secara independen. Setelah kegagalan tidak terencana, jika kontinuitas tidak diketahui, jangan membuat slot baru dan berpura-pura melanjutkan; bangun kembali dari cadangan atau snapshot tepercaya dan lakukan rekonsiliasi berdasarkan kunci, transaksi, dan LSN."
Pembahasan Mendalam Langkah demi Langkah
Langkah 1: Modelkan slot, LSN, dan kemajuan konsumen
Replication slot logis mewakili aliran perubahan yang dapat diputar ulang dalam urutan sumber. restart_lsn adalah posisi WAL paling awal yang masih harus dipertahankan; kemajuan yang diakui konsumen biasanya diwakili oleh confirmed_flush_lsn atau offset spesifik konektor. Keduanya menjawab pertanyaan berbeda: yang pertama mengontrol pembersihan WAL, sedangkan yang kedua menunjukkan seberapa jauh konsumen telah memproses.
Setiap konsumen independen harus memiliki slot independen atau lapisan siaran (broadcast) eksplisit. Banyak konsumen yang bersaing untuk satu slot single-consumer dapat menyebabkan konsumen yang tidak menerima perubahan menjadi tidak lengkap secara diam-diam. Pantau WAL yang tertahan, posisi terkonfirmasi, penundaan pembacaan, transaksi tertua yang belum diproses, dan sisa ruang disk, bukan hanya antrean aplikasi.
Langkah 2: Buat titik aman yang dapat dibuktikan untuk failover terencana
Failover terencana dapat menggunakan jeda read-only atau pengosongan (drain) singkat. Catat offset aman terakhir setiap konsumen, tunggu hingga pemutaran fisik standby mencakup status slot yang diperlukan, lalu periksa apakah failover slot dapat digunakan di standby. PostgreSQL memerlukan konfirmasi bahwa slot disinkronkan; failover_ready berarti slot disinkronkan, non-sementara, dan tidak memiliki alasan pembatalan.
freeze_or_throttle_writes()
stop_consumers_after_recording_offsets()
wait_until(standby_replay_lsn >= required_slot_positions)
assert all(required_slots on standby are synced and valid)
promote(standby)
verify_slot_positions_are_monotonic()
restart_consumers_from_last_safe_offsets()
reconcile_sampled_rows_and_transactions()Subscriber PostgreSQL dapat menggunakan pengaturan failover langganan atau slot. Konektor Debezium harus mempertahankan offset-nya, mengonfirmasi slot yang cocok ada pada primary baru, dan membuktikan bahwa konektor dapat melanjutkan dari LSN yang sama. Kode sukses pada skrip bukanlah pengganti untuk pemeriksaan status tersebut.
Langkah 3: Tangani kegagalan tidak terencana dan pengiriman duplikat
Ketika primary mati tiba-tiba, standby mungkin memuat posisi WAL yang lebih lama, dan konsumen mungkin telah menerima peristiwa tanpa mencatat offset-nya secara persisten. Izinkan tumpang tindih terbatas dan lakukan deduplikasi di downstream berdasarkan LSN sumber, ID transaksi, atau kunci idempoten domain. Slot primary baru harus berasal dari status yang disinkronkan; jika kontinuitas tidak diketahui, membuat slot pada posisi WAL saat ini tidak dapat memulihkan LSN yang dibuang.
Jika primary lama kembali aktif, jangan biarkan menerima penulisan bersamaan dengan primary baru. Isolasikan, tetapkan timeline yang otoritatif, dan bangun kembali replikasi fisik atau logis. Setiap penyambungan ulang harus dimulai dari snapshot yang konsisten atau posisi log eksplisit serta merekonsiliasi transaksi, penghapusan, dan batasan lintas tabel selama jeda waktu tersebut.
Langkah 4: Kendalikan pembatalan slot dan pertumbuhan WAL
Slot yang terus tertinggal akan menahan WAL dan mengancam disk primary serta keamanan ID transaksi. Lindungi primary terlebih dahulu, lalu putuskan apakah slot masih dapat dipulihkan: jeda konsumen non-kritis, batasi penulisan, atau tambahkan penyimpanan sementara hanya dengan anggaran yang jelas. Jika slot dihapus, dibatalkan, atau kekurangan LSN yang diperlukan, membuat slot dengan nama yang sama tidak dapat memulihkan riwayat.
Bangun kembali konsumen dari cadangan konsisten atau snapshot penuh terbaru, catat posisi snapshot, dan konsumsi perubahan setelah posisi tersebut. Rekonsiliasi berdasarkan versi kunci, ID transaksi, tombstone penghapusan, dan jumlah yang diharapkan. Pertahankan status konsumen dalam kondisi terdegradasi hingga rekonsiliasi berhasil; "konsumen terhubung" tidak berarti data sudah lengkap.
Langkah 5: Verifikasi failover dengan latihan (drill) dan pengukuran
Lakukan simulasi peralihan terencana tanpa penulisan, konsumen yang tertinggal, sinkronisasi slot yang tertunda, hilangnya primary secara tiba-tiba, pesan duplikat, kembalinya primary lama yang tidak disengaja, pembatalan slot, perubahan skema, dan transaksi besar. Catat timeline primary dan standby, status slot, restart_lsn, confirmed_flush_lsn, offset konsumen, batasan transaksi, dan jumlah data bisnis.
Pemeriksaan penerimaan mencakup LSN yang monotonik, jumlah peristiwa duplikat dan hilang, usia transaksi tertua yang belum diproses, WAL yang tertahan, RTO/RPO failover, waktu pemulihan konsumen, dan perbedaan versi sampel antara basis data dan downstream. Ketidakkonsistenan terkecil yang ditemukan setelah injeksi kesalahan harus dapat diputar ulang dari cadangan atau posisi log yang disimpan; hal itu menunjukkan jalur perbaikan yang nyata.
Contoh Jawaban Berkualitas Tinggi
"Saya akan mendefinisikan kontinuitas terlebih dahulu: slot primary baru mencakup posisi aman terakhir konsumen dan LSN sumber meningkat secara monotonik. Duplikat dapat diterima, celah tanpa peringatan tidak. Setiap konsumen non-PostgreSQL mendapatkan slotnya sendiri, dan offset konektor, status slot, serta rekonsiliasi bisnis membentuk satu set bukti.
Untuk failover terencana, saya menjeda atau membatasi penulisan, mencatat setiap offset konsumen, menunggu pemutaran fisik standby mencakup status slot, dan memverifikasi bahwa setiap failover slot disinkronkan, non-sementara, dan valid. Saya menghentikan konektor, mempromosikan standby, memverifikasi posisi monotonik, dan melanjutkan dari offset aman terakhir. Subscriber PostgreSQL dapat menggunakan pengaturan failover bawaan; konsumen Debezium harus memverifikasi slot baru dan LSN secara independen.
Untuk kegagalan tidak terencana, saya mengizinkan tumpang tindih terbatas dan membuat target idempoten berdasarkan LSN atau ID transaksi. Jika kontinuitas slot tidak dapat dibuktikan, saya tidak membuat slot baru dan berpura-pura melanjutkan. Saya membangun kembali dari cadangan yang konsisten atau snapshot penuh, mengonsumsi perubahan berikutnya, dan merekonsiliasi kunci, penghapusan, dan batasan transaksi. Simulasi latihan menginjeksikan keterlambatan sinkronisasi slot, duplikat, kembalinya primary lama, dan transaksi besar sambil mengukur WAL yang tertahan, RPO failover, duplikat atau celah, dan perbedaan versi downstream."
Kesalahan Umum
- Hanya mengganti DNS atau string koneksi → logical slot dan offset konsumen tidak menjadi kontinu secara otomatis → kendalikan failover berdasarkan status slot, LSN, dan konsumen.
- Menganggap sinkronisasi standby fisik sebagai kesiapan logical slot → sinkronisasi slot bersifat asinkron dan dapat tertinggal dari konsumen → periksa status sinkronisasi, validitas, dan pemutaran setiap slot.
- Berbagi satu slot di antara beberapa konsumen → pengiriman single-consumer diam-diam membuat konsumen lain tidak lengkap → gunakan satu slot per konsumen independen atau lapisan siaran.
- Membuat slot baru di primary baru → rentang LSN yang sudah hilang tidak dapat dipulihkan → bangun kembali dari snapshot saat kontinuitas tidak diketahui.
- Memperlakukan
confirmed_flush_lsnsebagairestart_lsn→ yang satu adalah kemajuan konsumen dan yang lainnya mengontrol retensi WAL → pantau dan jelaskan keduanya secara terpisah. - Menjanjikan exactly-once sebagai properti failover → celah waktu crash tetap menciptakan duplikat → gunakan at-least-once ditambah efek samping idempoten dan ukur duplikatnya.
- Menyambungkan kembali primary lama secara langsung → dual writer menciptakan timeline dan LSN yang divergen → isolasikan, pilih otoritas, dan bangun kembali pada timeline baru.
- Hanya melatih ketersediaan basis data → pembatalan slot, transaksi panjang, dan pertumbuhan WAL mengekspos risiko data → injeksikan jeda konsumen, penumpukan slot, dan transaksi besar.
- Menyatakan pemulihan selesai hanya karena konsumen terhubung → keberhasilan koneksi tidak membuktikan baris atau penghapusan telah lengkap → rekonsiliasi kunci, batasan transaksi, dan jumlah data bisnis.
Pertanyaan Lanjutan dan Jawaban
Pertanyaan Lanjutan 1: Haruskah failover terencana menghentikan penulisan?
Tidak selalu, tetapi melanjutkan penulisan memperbesar jendela pembuktian. Jika basis data dan mekanisme sinkronisasi slot membuktikan bahwa standby mencakup setiap posisi yang diperlukan, jendela read-only bisa singkat. Jika tidak, membatasi penulisan secara singkat lebih aman daripada mengganti gerbang LSN dengan asumsi 'biasanya cepat'. Tunggu transaksi yang di-commit selesai dan catat batasannya.
Pertanyaan Lanjutan 2: Bagaimana konsumen non-PostgreSQL mengetahui slot baru kontinu?
Pertahankan offset konektor dan LSN sumber. Sebelum beralih, konfirmasikan bahwa slot standby disinkronkan pada atau melampaui posisi tersebut; setelah beralih, baca awal slot baru dan periksa sifat monotoniknya. Jika offset hanya berisi waktu pesan dan tanpa LSN, kontinuitas tidak terbukti; bangun kembali atau tambahkan metadata posisi sumber.
Pertanyaan Lanjutan 3: Bagaimana dengan transaksi besar selama failover?
Bedakan status committed, uncommitted, dan yang didekode sebagian. Jika downstream memerlukan atomisitas transaksi, sebarkan batasan BEGIN/COMMIT dan buang fragmen yang tidak lengkap setelah pemulihan. Jika konsistensi akhir (eventual consistency) tingkat baris sudah cukup, nyatakan aturan visibilitas perantara dan pemutaran ulang. Urutan kedatangan baris individual tidak membuktikan transaksi yang lengkap.
Pertanyaan Lanjutan 4: Bisakah Anda menghapus slot saat WAL memenuhi disk?
Hanya setelah mengonfirmasi bahwa konsumen tidak lagi memerlukan riwayat tersebut dan pembangunan kembali snapshot sudah siap. Menghapus slot akan mengosongkan ruang tetapi membuang perubahan yang belum dibaca secara permanen. Simpan posisi, cadangan, dan rencana rekonsiliasi terlebih dahulu; setelah membangun kembali, buktikan tidak ada celah dari snapshot baru ke posisi sumber saat ini.