Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.
01Bagaimana cara kerja database replication?
Satu node, yaitu leader, menerima write dan mencatat setiap perubahan di write-ahead log-nya. Follower menerima record log itu, baik sebagai file kiriman maupun stream terus-menerus, lalu me-replay-nya agar tetap identik. Replication bisa asynchronous, saat leader tidak menunggu, atau synchronous, saat leader menunggu follower.
02Apa beda synchronous dan asynchronous replication?
Pada asynchronous replication, leader melaporkan commit berhasil sebelum follower mana pun punya datanya, jadi commit cepat tetapi write terbaru bisa hilang jika leader mati. Pada synchronous replication, leader menunggu minimal satu follower mengonfirmasi, sehingga tidak ada yang hilang setelah di-acknowledge, tetapi tiap commit membayar satu round trip jaringan dan follower yang mati bisa menahan write.
03Apa itu replication lag dan bagaimana mengukurnya?
Replication lag adalah selisih antara yang sudah ditulis leader dan yang sudah diterima atau di-replay follower. Di PostgreSQL Anda bisa membandingkan pg_current_wal_lsn di primary dengan replay_lsn di pg_stat_replication memakai pg_wal_lsn_diff, yang memberi lag dalam byte WAL. Pasang alert untuknya, karena lag yang membesar berarti risiko stale read sekaligus window kehilangan data.
04Apa itu split-brain pada database cluster?
Split-brain adalah kondisi saat partisi jaringan atau kegagalan palsu membuat dua node sama-sama bertindak sebagai leader, masing-masing menerima write yang tidak dilihat yang lain. Hasilnya data yang bercabang dan harus direkonsiliasi manual. Pencegahannya adalah quorum voting, agar hanya sisi dengan mayoritas yang tetap bisa menulis, dan fencing, yang menghentikan leader lama sebelum yang baru dipromosikan.
05Kapan sebaiknya memakai multi-leader atau leaderless replication dibanding leader-follower?
Pakai multi-leader saat beberapa site masing-masing perlu menerima write lokal atau client harus bisa bekerja offline, dan pakai desain quorum leaderless seperti Dynamo untuk workload key-value yang harus selalu bisa ditulis. Keduanya memaksa Anda mendeteksi dan menyelesaikan write yang bentrok. Untuk kebanyakan aplikasi bisnis dengan satu database utama, single-leader replication lebih sederhana dan sudah cukup.
Database Replication: Leader-Follower, Sync vs Async
Cara kerja database replication: WAL shipping, trade-off commit sync vs async, failover, split-brain, serta kapan multi-leader atau leaderless dipakai.
Database replication menyalin setiap perubahan dari satu leader ke satu atau lebih follower, biasanya dengan mengirim write-ahead log. Replication asynchronous membuat commit cepat tetapi bisa kehilangan tulisan terbaru saat failover. Replication synchronous menunggu follower, menukar latency dengan durability. Fencing dan quorum mencegah split-brain, yaitu dua node sama-sama merasa jadi leader.
Pertanyaan yang membuat saya membaca bab replication dengan serius sebenarnya sederhana: kalau container Postgres di balik sistem point-of-sale mati di tengah shift, apa persisnya yang hilang? Jawabannya bergantung pada satu setting dan pada server kedua yang tidak dimiliki kebanyakan deployment kecil.
Post ini menjelaskan leader-follower replication dari level log, lalu trade-off commit, failover, split-brain, dan dua topologi lainnya. Setiap setting berasal dari dokumentasi PostgreSQL, klaim lainnya dari paper Dynamo dan Wikipedia, dan setiap angka pada contoh hitungan dikutip atau diturunkan dari asumsi yang saya tulis jelas. Saya tidak menjalankan benchmark apa pun untuk post ini.
Apa itu leader-follower replication, dan kenapa dipakai?
Pada leader-follower replication (disebut juga primary-standby atau master-replica), satu node menerima semua write dan satu atau lebih follower menerima salinan setiap perubahan. Tim menambah follower karena tiga alasan yang berbeda, dan penting tahu mana yang sedang Anda beli.
Durability: salinan kedua data di mesin lain tetap selamat saat mesin pertama hilang.
Availability: follower bisa dipromosikan jadi leader saat leader gagal, sehingga downtime hitungan menit, bukan restore dari backup.
Read scaling: query laporan dan dashboard bisa jalan di follower, tidak berebut resource dengan traffic checkout di leader.
Mekanisme di bawahnya adalah write-ahead log. Aturan inti PostgreSQL: perubahan pada data file baru boleh ditulis setelah WAL record yang menjelaskannya di-flush ke penyimpanan permanen, dan itulah yang memungkinkan recovery setelah crash dengan memutar ulang log. Follower melakukan replay yang sama secara terus-menerus, dengan log yang datang lewat jaringan, bukan dari disk lokal. Konfigurasi di bawah adalah minimum untuk streaming standby dengan replication slot dan quorum satu.
# --- primary: postgresql.conf ---
wal_level = replica # enough WAL detail for physical replicas
max_wal_senders = 5 # one slot per connected standby, plus headroom
max_replication_slots = 5 # the primary keeps WAL until each slot has it
synchronous_commit = on # the default; only bites once standbys are named
synchronous_standby_names = 'ANY 1 (replica_a, replica_b)'
# quorum: any ONE of the two must confirm
# --- primary: pg_hba.conf ---
# the special database name "replication" is how a standby is allowed in
host replication replicator 10.0.0.0/24 scram-sha-256
# --- standby: postgresql.conf (plus an empty standby.signal file) ---
primary_conninfo = 'host=10.0.0.10 user=replicator application_name=replica_a'
primary_slot_name = 'replica_a_slot'
Bagaimana WAL shipping bekerja?
Ada dua jalur transport. File-based log shipping menyalin file segmen WAL yang sudah penuh ke standby; dokumentasi menyebut ini asynchronous menurut definisinya, karena record dikirim setelah transaksi commit, sehingga ada window kehilangan data yang bisa diperkecil archive_timeout sampai beberapa detik dengan biaya bandwidth. Streaming replication sebaliknya: standby terhubung ke primary, dan primary mengirim WAL record begitu dibuat tanpa menunggu satu file penuh.
Streaming bersifat asynchronous secara default, dan dokumentasi menyebut delay-nya biasanya di bawah satu detik bila standby cukup kuat mengikuti beban. Dua detail operasional sering menjebak. Tanpa replication slot atau wal_keep_size yang cukup besar, primary bisa mendaur ulang WAL sebelum standby yang lambat menerimanya, dan standby itu harus dibangun ulang dari base backup baru. Dengan slot, risikonya terbalik: primary menyimpan WAL sampai standby menyusul, jadi standby yang mati bisa memenuhi disk. Lag diukur dengan membandingkan pg_current_wal_lsn di primary dengan posisi WAL yang sudah diterima standby.
-- On the primary: how far behind is each standby, in bytes of WAL?
SELECT application_name,
sync_state, -- async | sync | potential | quorum
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag_bytes
FROM pg_stat_replication;
-- On a standby: has it received everything the primary has written?
SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();
-- Per transaction, not per server: a cheap audit-log write can skip the wait.
BEGIN;
SET LOCAL synchronous_commit TO off; -- this commit will not wait for any standby
INSERT INTO page_view_log (path) VALUES ('/blog/replication');
COMMIT;
Physical standby memutar ulang perubahan level byte yang sama dengan primary, jadi harus memakai major version yang sama dan tidak bisa punya tabel tambahan. Logical replication, yang mengirim perubahan per baris dan mengizinkan lompat versi, adalah alat yang berbeda; angle itu sudah saya bahas di post zero-downtime upgrade.
Synchronous atau asynchronous: commit menunggu apa?
Trade-off commit bermuara pada satu pertanyaan: saat client menerima success, datanya sudah ada di mana saja? Setting synchronous_commit di PostgreSQL menjawabnya bertingkat, dan baru menjangkau standby setelah synchronous_standby_names berisi nilai.
synchronous_commit
Success dikembalikan setelah
Yang tetap selamat
off
Tidak menunggu flush WAL sama sekali
Tidak ada jaminan untuk beberapa saat terakhir; delay maksimum yang didokumentasikan adalah tiga kali wal_writer_delay, tetapi database tetap konsisten
local
Flush WAL lokal di primary saja
Crash proses di primary; bukan hilangnya mesin primary
remote_write
Standby menerima record dan menulisnya ke operating system
Crash PostgreSQL di standby, bukan crash operating system di sana
on (default)
Standby sudah flush record ke penyimpanan durable
Hilang hanya jika primary dan semua synchronous standby kehilangan storage-nya
remote_apply
Standby sudah replay record, jadi query di sana bisa melihat datanya
Sama seperti on, ditambah read di standby yang melihat write Anda sendiri
Harga dari menunggu adalah latency, dan hitungannya sederhana. Angka di bawah adalah asumsi yang dibulatkan, bukan hasil pengukuran; ganti dengan waktu fsync dan round-trip Anda sendiri.
Assumed inputs (illustrative, measure your own):
local WAL fsync = 1.0 ms
network round trip = 0.5 ms (same region)
standby WAL fsync = 1.0 ms
synchronous_commit = local -> 1.0 ms per commit
synchronous_commit = on -> 1.0 + 0.5 + 1.0 = 2.5 ms per commit
(the commit record is flushed locally first, then sent; the primary
waits for the standby's flush acknowledgement)
One connection committing serially:
local : 1000 ms / 1.0 ms = 1000 commits per second
on : 1000 ms / 2.5 ms = 400 commits per second
Async data-loss window (assumed): WAL written at 2 MB/s, standby 1.5 s behind
2 MB/s x 1.5 s = 3 MB of committed WAL that dies with the primary
Quorum arithmetic (majority = floor(N / 2) + 1):
N = 3 -> majority 2 (survives 1 failure, can tell a minority side apart)
N = 2 -> majority 2 (survives 0 failures: a partition leaves nobody sure)
Leaderless (Dynamo style), N = 3 replicas:
W = 2, R = 2 -> R + W = 4 > 3, every read overlaps the latest write
W = 1, R = 1 -> R + W = 2 <= 3, a read can miss the newest value
Setting ini berlaku per transaksi, bukan per server. Commit pembayaran bisa menunggu standby, sementara insert log page-view memakai SET LOCAL synchronous_commit TO off, cara paling murah untuk tidak membayar 2.5 ms di tempat yang durability-nya tidak penting. Satu hal lagi yang perlu didesain: pada synchronous replication, commit bisa tidak pernah selesai jika synchronous standby yang diwajibkan crash, jadi namai beberapa kandidat dan pakai FIRST atau ANY, bukan satu standby bernama.
Synchronous replication mengubah standby yang mati menjadi primary yang mati, kecuali Anda menyiapkan kandidat cadangan. Jika satu-satunya synchronous standby mati, write tertahan sampai Anda menurunkan syaratnya dan reload konfigurasi. Putuskan dari awal Anda mau gagal ke arah mana: write berhenti atau write hilang.
Apa yang terjadi saat failover?
Failover adalah tindakan mempromosikan follower setelah leader gagal. PostgreSQL sengaja tidak menyertakan software yang mendeteksi kegagalan itu; dokumentasi menyebut banyak tool eksternal untuk itu, jadi deteksi dan pemindahan IP adalah tugas tooling Anda, bukan database. Urutannya sama apa pun tool yang menjalankannya.
Detect: heartbeat gagal cukup lama sampai leader dinyatakan mati. Timeout terlalu pendek menyebabkan failover palsu saat jaringan berkedip.
Fence: pastikan leader lama tidak bisa lagi menerima write, dengan memutus network, storage, atau listriknya.
Choose: promosikan follower yang sudah menerima WAL paling banyak, karena follower asynchronous bisa kehilangan bagian ekor.
Redirect: pindahkan virtual IP atau perbarui connection pooler agar aplikasi menjangkau leader baru.
Rebuild: pasang kembali leader lama sebagai follower, yang mungkin perlu di-rewind atau di-clone ulang, lalu buat ulang replication slot.
Dokumentasi blak-blakan soal harga failover asynchronous: sebagian transaksi yang sudah commit mungkin belum sampai ke standby, dan kehilangan datanya sebanding dengan replication delay saat failover. Dengan asumsi 2 MB per detik WAL dan lag 1.5 detik dari contoh hitungan, itu sekitar 3 MB write yang sudah di-acknowledge dan dianggap aman oleh aplikasi.
Apa itu split-brain, dan bagaimana mencegahnya?
Split-brain terjadi saat partisi atau kegagalan palsu membuat dua node sama-sama merasa jadi leader, sehingga masing-masing menerima write yang tidak pernah dilihat yang lain. Artikel Wikipedia menggambarkan obat pesimistisnya sebagai quorum: partisi yang memegang mayoritas suara tetap available sementara yang lain masuk mode auto-fencing. Bab failover PostgreSQL menyebut separuh lainnya, STONITH (shoot the other node in the head), sebagai mekanisme yang memberi tahu primary lama yang menyala kembali bahwa ia bukan primary lagi.
Hitungannya menjelaskan kenapa tiga node adalah minimum praktis. Mayoritas dari N adalah floor(N / 2) + 1, jadi tiga node menoleransi satu kegagalan dan dua node yang selamat bisa mengalahkan suara node yang terisolasi. Dua node butuh dua suara, sehingga partisi membuat kedua sisi tidak yakin; Wikipedia menyebut peluang cluster dua node tanpa witness gagal total sedikitnya 50 persen sampai manusia turun tangan. Dokumentasi PostgreSQL sendiri menyebut witness server karena alasan ini, sambil mengingatkan bahwa kompleksitas tambahannya perlu dirancang dan diuji dengan teliti.
Setelan synchronous quorum membantu dari sisi data. Dengan ANY 1 dari dua standby bernama, standby yang dipromosikan dijamin memegang setiap commit yang sudah di-acknowledge, karena sedikitnya satu dari mereka mengonfirmasi tiap commit. Quorum melindungi data; fencing melindungi dari dua writer. Anda butuh keduanya.
Pilih fail closed. Leader yang berhenti menerima write saat kehilangan kontak dengan mayoritas memang menyebalkan semenit; leader yang terus menulis di sisi yang salah dari partisi adalah proyek rekonsiliasi sepekan.
Bagaimana dengan multi-leader dan leaderless replication?
Leader-follower menjadi default karena hanya punya satu writer sehingga tidak ada write conflict. Dua alternatifnya menghapus writer tunggal itu dan membayarnya di tempat lain.
Topologi
Siapa yang menerima write
Conflict
Cocok untuk
Leader-follower
Satu leader
Tidak ada pada write; follower bisa lag pada read
Kebanyakan database aplikasi, termasuk back end ERP dan POS
Multi-leader
Satu leader per site atau per node
Edit bersamaan harus dideteksi dan diselesaikan
Beberapa region yang masing-masing butuh write lokal, atau client yang bisa offline
Leaderless
Replica mana pun, memakai quorum R dan W
Diselesaikan saat read atau lewat vector clock dan logika aplikasi
Workload key-value yang harus selalu bisa ditulis, seperti shopping cart Dynamo
Sistem leaderless memakai hitungan quorum sebagai pengganti leader. Pada paper Dynamo, dengan N replica, write menunggu W acknowledgement dan read menunggu R respons, dan memilih R ditambah W lebih besar dari N membuat himpunan read dan write saling beririsan. Dengan N 3, W 2 dan R 2 hasilnya 4, lebih besar dari 3, sedangkan W 1 dan R 1 hasilnya 2 dan bisa mengembalikan data usang. Paper itu juga menjelaskan sloppy quorum dan rekonsiliasi vector-clock, yaitu penanganan conflict yang sengaja dihindari sistem single-leader.
Setup mana yang sebaiknya dipilih tim kecil?
Untuk aplikasi bisnis dengan satu instance Postgres, titik awal yang jujur adalah streaming replication single-leader dengan satu atau dua follower. Lewati checklist ini sebelum menambah sesuatu yang lebih rumit.
Apakah follower berada di mesin fisik dan failure domain yang berbeda? Replica di VPS atau disk yang sama tidak melindungi dari apa pun kecuali crash container.
Bisakah Anda menyatakan toleransi kehilangan data dalam detik write? Jika jawabannya nol untuk tabel terkait uang, pakai synchronous_commit on dengan ANY 1 di dua standby.
Sudahkah Anda mengatur replication slot atau wal_keep_size, plus alert untuk slot lag agar follower yang mati tidak memenuhi disk primary?
Apakah ada langkah fencing tertulis di runbook failover, bukan hanya perintah promote?
Sudahkah Anda berlatih failover dan rebuild leader lama, minimal sekali, pada salinan?
Di satu VPS, tempat pekerjaan ERP dan POS saya berjalan, follower baru berguna jika ia berada di tempat lain, dan backup dengan point-in-time recovery menutup banyak risiko yang sama dengan kompleksitas lebih rendah. Desain multi-leader dan leaderless baru sepadan dengan penanganan conflict-nya hanya jika Anda memang butuh write di beberapa tempat sekaligus.
Replica adalah salinan kedua ditambah satu keputusan. Salinannya bagian yang mudah, yaitu aliran WAL. Keputusannya adalah commit menunggu apa, siapa yang boleh jadi leader, dan bagaimana leader lama dihentikan. Selesaikan ketiganya sebelum hari Anda membutuhkannya.