Prompt dan Peranan yang Berkenaan
Sebuah primary PostgreSQL menstrim perubahan pesanan ke gudang data (warehouse) dan perkhidmatan carian melalui replikasi logikal. Primary mungkin gagal semasa pengguna (consumers) ketinggalan. Reka bentuk failover terancang dan tidak terancang, terangkan cara mengesahkan bahawa slot logikal pada standby boleh mengambil alih, cara mengelakkan julat LSN pendua atau terlompat, dan cara memulihkan keadaan apabila kesinambungan slot tidak dapat dibuktikan.
Ini sesuai untuk temu bual backend, platform pangkalan data, infrastruktur data, dan SRE. Bezakan pelanggan (subscribers) PostgreSQL daripada pengguna bukan PostgreSQL seperti Debezium: pelanggan PostgreSQL boleh menggunakan tetapan failover terbina dalam, manakala pengguna bukan PostgreSQL masih memerlukan bukti bebas merentasi keadaan penyambung (connector), slot, dan penyesuaian (reconciliation). "Standby telah disegerakkan" tidak membuktikan bahawa setiap pengguna logikal boleh menyambung tugas secara lancar.
Perkara yang Diuji oleh Penemu Bual
Jawapan yang kukuh menyatakan invarian yang boleh disahkan: strim logikal pada primary baharu tidak boleh bergerak ke belakang; pengguna menyambung semula dari kedudukan yang disahkan, dengan pendua dibenarkan tetapi jurang senyap dilarang sama sekali; dan failover bergantung kepada penyegerakan slot serta kemajuan pengguna. Calon harus memisahkan failover terancang, di mana penulisan boleh dijeda dan pengguna diselesaikan (drained), daripada kegagalan tidak terancang, di mana sandaran (backup), snapshot penuh, dan penyesuaian mungkin merupakan satu-satunya kaedah pembaikan yang selamat. Mengarahkan DNS ke standby semata-mata tidak menyelesaikan isu slot, pengekalan WAL, atau pengguna bukan PostgreSQL.
Soalan untuk Dijelaskan Sebelum Menjawab
- Apakah pengguna (consumers) tersebut? Pelanggan PostgreSQL, Debezium, pemuat gudang data (warehouse loaders), dan penyahkod tersuai mempunyai antara muka kemajuan dan pemulihan yang berbeza.
- Adakah pendua boleh diterima? Penghantaran sekurang-kurangnya sekali (at-least-once) biasanya boleh diterima apabila sasaran melakukan penyahduplikasian (deduplicate) mengikut LSN, ID transaksi, atau kunci keidempotanan (idempotency key); skrip tidak boleh menjanjikan tepat sekali (exactly-once) hanya melalui pernyataan semata-mata.
- Adakah ini failover terancang atau bencana? Pertukaran terancang boleh menjeda penulisan dan menunggu standby; selepas kegagalan tidak terancang, LSN terakhir yang dikomit dan disahkan oleh pengguna mungkin tidak dapat diketahui.
- Adakah sempadan transaksi merentasi jadual penting? Jika hiliran (downstream) memerlukan paparan pesanan dan baris pesanan yang atomik, sebarkan sempadan transaksi dan bukannya membandingkan LSN satu baris.
- Berapa banyak WAL yang boleh dikekalkan? Slot yang ketinggalan menghalang pembersihan WAL, berisiko menghabiskan ruang cakera primary; slot yang tidak sah boleh mewujudkan jurang yang tidak dapat dipulihkan.
- Bolehkah pengguna dibina semula daripada snapshot? Jika kesinambungan tidak dapat dibuktikan, sediakan snapshot penuh, penyesuaian versi, dan pelan degradasi atau penyelenggaraan.
Rangka Kerja Jawapan 30 Saat
"Saya akan menyatakan invarian secara eksplisit: kedudukan slot primary baharu merangkumi kedudukan terakhir pengguna yang disahkan, dan LSN sumber yang dipulihkan bergerak secara monotonik. Peristiwa pendua boleh dimainkan semula, tetapi tiada julat yang boleh dilangkau secara senyap. Untuk failover terancang, jeda atau hadkan (throttle) penulisan, sahkan bahawa failover slots disegerakkan ke standby dan standby berada di hadapan pengguna, hentikan penyambung selepas merekodkan LSN yang selamat, naikkan taraf (promote) standby, dan sambung semula pengguna.
PostgreSQL 17 boleh menyegerakkan failover slots ke standby secara tidak segerak (asynchronously), tetapi pertukaran mesti menyemak bahawa setiap slot wujud, disegerakkan, bukan sementara (non-temporary), dan tidak mempunyai sebab ketidaksahan. Debezium dan pengguna bukan PostgreSQL lain mesti mengesahkan slot dan LSN mereka secara bebas. Selepas kegagalan tidak terancang, jika kesinambungan tidak diketahui, jangan cipta slot baharu dan berpura-pura untuk meneruskan; bina semula daripada sandaran atau snapshot yang dipercayai dan selaraskan mengikut kunci, transaksi, dan LSN."
Panduan Mendalam Langkah demi Langkah
Langkah 1: Modelkan slot, LSN, dan kemajuan pengguna
Replication slot logikal mewakili strim perubahan yang boleh dimainkan semula mengikut urutan sumber. restart_lsn ialah kedudukan WAL terawal yang masih mesti dikekalkan; kemajuan pengguna yang diperakui biasanya diwakili oleh confirmed_flush_lsn atau ofset khusus penyambung. Kedua-duanya menjawab soalan yang berbeza: yang pertama mengawal penambakan semula WAL, manakala yang kedua menyatakan sejauh mana pengguna telah memproses data.
Setiap pengguna bebas harus mempunyai slot bebas atau lapisan penyiaran (broadcast layer) yang jelas. Pelbagai pengguna yang bersaing untuk satu slot pengguna tunggal boleh menyebabkan pengguna yang tidak menerima perubahan menjadi tidak lengkap secara senyap. Pantau WAL yang dikekalkan, kedudukan yang disahkan, kelewatan membaca, transaksi tertua yang belum diproses, dan ruang simpanan cakera, bukan hanya baris gilir aplikasi.
Langkah 2: Cipta titik selamat yang boleh dibuktikan untuk failover terancang
Failover terancang boleh menggunakan tetingkap baca sahaja atau tetingkap penyelesaian (drain window) yang singkat. Rekod ofset selamat terakhir setiap pengguna, tunggu sehingga main balik fizikal standby merangkumi keadaan slot yang diperlukan, dan kemudian semak bahawa failover slots boleh digunakan pada standby. PostgreSQL memerlukan pengesahan bahawa slot telah disegerakkan; failover_ready bermaksud slot disegerakkan, bukan sementara, dan tidak mempunyai sebab ketidaksahan.
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()Pelanggan PostgreSQL boleh menggunakan tetapan failover langganan atau slot. Penyambung Debezium mesti mengekalkan ofsetnya, mengesahkan bahawa slot yang sepadan wujud pada primary baharu, dan membuktikan bahawa ia boleh diteruskan daripada LSN yang sama. Kod kejayaan skrip bukan pengganti bagi semakan keadaan tersebut.
Langkah 3: Kendalikan kegagalan tidak terancang dan penghantaran pendua
Apabila primary terputus, standby mungkin mengandungi kedudukan WAL yang lebih awal, dan pengguna mungkin telah menerima peristiwa tanpa merekodkan ofsetnya secara kekal. Benarkan pertindihan terhad dan lakukan penyahduplikasian di hiliran mengikut LSN sumber, ID transaksi, atau kunci keidempotanan domain. Slot primary baharu mesti datang daripada keadaan yang disegerakkan; jika kesinambungan tidak diketahui, mencipta slot pada kedudukan WAL semasa tidak dapat memulihkan LSN yang telah dibuang.
Sekiranya primary lama kembali beroperasi, jangan benarkan ia menerima penulisan bersama-sama primary baharu. Asingkannya, tetapkan garis masa (timeline) yang berwibawa, dan bina semula replikasi fizikal atau logikal. Sebarang penyambungan semula mesti bermula daripada snapshot yang konsisten atau kedudukan log yang jelas dan menyelaraskan transaksi, pemadaman, dan sempadan merentasi jadual sepanjang tetingkap tersebut.
Langkah 4: Bendung ketidaksahan slot dan pertumbuhan WAL
Slot yang terus ketinggalan mengekalkan WAL dan mengancam keselamatan cakera primary serta keselamatan ID transaksi. Lindungi primary terlebih dahulu, kemudian tentukan sama ada slot masih boleh dipulihkan: jeda pengguna bukan kritikal, hadkan penulisan, atau tambah storan sementara hanya dengan belanjawan yang jelas. Sekiranya slot telah digugurkan, tidak sah, atau kekurangan LSN yang diperlukan, mencipta slot dengan nama yang sama tidak dapat memulihkan sejarah.
Bina semula pengguna daripada sandaran konsisten terkini atau snapshot penuh, rekod kedudukan snapshot, dan gunakan perubahan selepas kedudukan tersebut. Selaraskan mengikut versi kunci, ID transaksi, tanda pemadaman (tombstone), dan kiraan yang dijangkakan. Kekalkan status pengguna sebagai terdegradasi sehingga penyesuaian lulus; "pengguna telah bersambung" bukan bermaksud kelengkapan data.
Langkah 5: Sahkan failover melalui latih tubi dan pengukuran
Lakukan latih tubi pertukaran terancang tanpa penulisan, pengguna yang ketinggalan, penyegerakan slot yang tertangguh, kehilangan primary secara tiba-tiba, mesej pendua, kepulangan primary lama secara tidak sengaja, ketidaksahan slot, perubahan skema, dan transaksi yang besar. Rekod garis masa primary dan standby, keadaan slot, restart_lsn, confirmed_flush_lsn, ofset pengguna, sempadan transaksi, dan kiraan perniagaan.
Pemeriksaan penerimaan merangkumi LSN yang monotonik, kiraan peristiwa pendua dan hilang, usia transaksi tertua yang belum diproses, WAL yang dikekalkan, RTO/RPO failover, masa pemulihan pengguna, dan perbezaan versi yang disampel antara pangkalan data dan hiliran. Ketidakkonsistenan terkecil yang ditemui selepas suntikan kerosakan (fault injection) harus boleh dimainkan semula daripada sandaran atau kedudukan log yang disimpan; ini menunjukkan laluan pembaikan yang sebenar.
Contoh Jawapan Berkualiti Tinggi
"Saya akan mentakrifkan kesinambungan terlebih dahulu: slot primary baharu merangkumi kedudukan selamat terakhir pengguna dan LSN sumber meningkat secara monotonik. Pendua boleh diterima, jurang senyap tidak boleh. Setiap pengguna bukan PostgreSQL mendapat slotnya sendiri, dan ofset penyambung, keadaan slot, serta penyesuaian perniagaan membentuk satu set bukti.
Untuk failover terancang, saya menjeda atau mengehadkan (throttle) penulisan, merekod setiap ofset pengguna, menunggu main balik fizikal standby merangkumi keadaan slot, dan mengesahkan bahawa setiap failover slot adalah disegerakkan, bukan sementara, dan sah. Saya menghentikan penyambung, menaikkan taraf (promote) standby, mengesahkan kedudukan monotonik, dan menyambung semula dari ofset selamat terakhir. Pelanggan PostgreSQL boleh menggunakan tetapan failover terbina dalam; pengguna Debezium mesti mengesahkan slot baharu dan LSN secara bebas.
Untuk kegagalan tidak terancang, saya membenarkan pertindihan terhad dan memastikan sasaran adalah idempotan mengikut LSN atau ID transaksi. Jika kesinambungan slot tidak dapat dibuktikan, saya tidak akan mencipta slot baharu dan berpura-pura untuk meneruskan. Saya membina semula daripada sandaran yang konsisten atau snapshot penuh, menggunakan perubahan yang menyusul, dan menyelaraskan kunci, pemadaman, serta sempadan transaksi. Latih tubi menyuntik kelewatan penyegerakan slot, pendua, kepulangan primary lama, dan transaksi besar sambil mengukur WAL yang dikekalkan, RPO failover, pendua atau jurang, dan perbezaan versi hiliran."
Kesilapan Biasa
- Hanya menukar DNS atau rentetan sambungan → slot logikal dan ofset pengguna tidak menjadi berterusan secara automatik → sandarkan (gate) failover pada keadaan slot, LSN, dan pengguna.
- Menganggap penyegerakan standby fizikal sebagai kesediaan slot logikal → penyegerakan slot adalah tidak segerak (asynchronous) dan mungkin ketinggalan di belakang pengguna → semak keadaan synced, valid, dan replay setiap slot.
- Berkongsi satu slot dalam kalangan pengguna → penghantaran pengguna tunggal secara senyap meninggalkan pengguna lain tidak lengkap → gunakan satu slot bagi setiap pengguna bebas atau lapisan penyiaran.
- Mencipta slot baharu pada primary baharu → julat LSN yang telah hilang tidak dapat dipulihkan → bina semula daripada snapshot apabila kesinambungan tidak diketahui.
- Menganggap
confirmed_flush_lsnsebagairestart_lsn→ satu adalah kemajuan pengguna dan satu lagi mengawal pengekalan WAL → pantau dan terangkan kedua-duanya secara berasingan. - Menjanjikan exactly-once sebagai sifat failover → tetingkap ranap masih menghasilkan pendua → gunakan at-least-once berserta kesan sampingan idempotan dan ukur pendua.
- Menyambung semula primary lama dengan serta-merta → penulis berganda (dual writers) mewujudkan garis masa dan LSN yang menyimpang → asingkannya, pilih autoriti, dan bina semula pada garis masa baharu.
- Hanya melatih ketersediaan pangkalan data → ketidaksahan slot, transaksi yang panjang, dan pertumbuhan WAL mendedahkan risiko data → suntik kelengahan pengguna, penimbunan slot, dan transaksi yang besar.
- Mengisytiharkan pemulihan apabila pengguna bersambung → kejayaan sambungan tidak membuktikan baris atau pemadaman adalah lengkap → selaraskan kunci, sempadan transaksi, dan kiraan perniagaan.
Soalan Susulan dan Maklum Balas
Susulan 1: Adakah failover terancang mesti menghentikan penulisan?
Tidak semestinya, tetapi meneruskan penulisan membesarkan tetingkap pembuktian. Jika pangkalan data dan mekanisme penyegerakan slot membuktikan bahawa standby merangkumi setiap kedudukan yang diperlukan, tetingkap baca sahaja boleh disingkatkan. Jika tidak, mengehadkan penulisan secara ringkas adalah lebih selamat daripada menggantikan kawalan (gate) LSN dengan andaian "ia biasanya pantas". Tunggu transaksi yang dikomit selesai dan rekod sempadannya.
Susulan 2: Bagaimanakah pengguna bukan PostgreSQL mengetahui slot baharu adalah berterusan?
Kekalkan ofset penyambung dan LSN sumber. Sebelum menukar, sahkan slot standby disegerakkan pada atau melebihi kedudukan tersebut; selepas menukar, baca permulaan slot baharu dan semak kemonotonikannya. Jika ofset hanya mengandungi masa mesej dan tiada LSN, kesinambungan tidak terbukti; bina semula atau tambah metadata kedudukan sumber.
Susulan 3: Bagaimana pula dengan transaksi yang besar semasa failover?
Bezakan keadaan yang dikomit, belum dikomit, dan dinyahkod sebahagiannya. Jika hiliran memerlukan keatoman transaksi, sebarkan sempadan BEGIN/COMMIT dan buang serpihan yang tidak lengkap selepas pemulihan. Sekiranya ketekalan akhirnya pada peringkat baris mencukupi, nyatakan peraturan keterlihatan perantaraan dan main balik. Susunan ketibaan baris individu tidak membuktikan transaksi yang lengkap.
Susulan 4: Bolehkah anda memadam slot apabila WAL memenuhi cakera?
Hanya selepas mengesahkan pengguna tidak lagi memerlukan sejarah tersebut dan binaan semula snapshot telah sedia. Menggugurkan slot mengosongkan ruang tetapi melepaskan perubahan yang belum dibaca secara kekal. Simpan kedudukan, sandaran, dan pelan penyesuaian terlebih dahulu; selepas membina semula, buktikan tiada jurang daripada snapshot baharu ke kedudukan sumber semasa.