Pernah nggak sih, lagi asyik-asyiknya aplikasi jalan lancar, tiba-tiba database server kamu mati? Semua layanan down, user komplain, dan kamu harus buru-buru restore backup sambil panik. Kalau pernah mengalami situasi kayak gitu, kamu pasti paham betapa sakitnya.
Nah, di sinilah PostgreSQL replication berperan. Dengan replication, kamu punya salinan database yang selalu sinkron di server lain. Kalau server utama tumbang, server cadangan bisa langsung ngambil alih — dan downtime yang tadinya bisa berjam-jam, sekarang cuma hitungan detik atau menit.
Di artikel ini, aku mau berbagi pengalaman setup PostgreSQL replication dari nol. Nggak cuma teori, tapi juga langkah-langkah praktis yang bisa kamu ikuti. Kita akan bahas streaming replication sebagai fondasi, lalu lanjut ke failover otomatis pakai repmgr supaya high availability-nya beneran jalan.
Kenapa Kamu Butuh PostgreSQL Replication?
Sebelum masuk ke teknis, penting banget buat paham kenapa kamu butuh ini. Aku dulu juga mikir, “Ah, backup harian udah cukup kok.” Ternyata nggak.
Backup itu bagus buat disaster recovery — misalnya server kamu kena ransomware atau harddisk-nya rusak total. Tapi backup nggak membantu kamu menghindari downtime. Proses restore bisa makan waktu puluhan menit sampai berjam-jam tergantung ukuran database. Dan selama proses itu, aplikasi kamu nggak bisa diakses.
Replication beda cerita. Kamu punya server kedua yang punya copy database yang hampir real-time. Kalau server utama (primary) jatuh, server kedua (standby) sudah siap menggantikan. Proses ini disebut failover, dan kalau di-setup dengan benar, bisa berjalan otomatis.
Ini beberapa skenario kenapa replication penting:
- High Availability (HA): Aplikasi tetap jalan walau salah satu server mati.
- Read Scaling: Standby server bisa dipakai buat baca data (read-only), mengurangi beban di primary.
- Backup Tanpa Downtime: Backup bisa diambil dari standby server tanpa mengganggu primary.
- Zero-Downtime Migration: Mau pindah ke server baru? Replication bikin prosesnya mulus.
Khusus untuk PostgreSQL, ada beberapa jenis replication:
- Streaming Replication — ini yang paling populer dan paling sering dipakai. Standby server menerima perubahan data secara real-time dari primary via streaming WAL (Write-Ahead Log).
- Logical Replication — lebih fleksibel, memungkinkan replicasi per-tabel, tapi setup-nya lebih rumit untuk HA.
- Synchronous vs Asynchronous — synchronous menjamin data sampai di standby sebelum transaksi dianggap selesai (zero data loss), sedangkan asynchronous lebih cepat tapi ada potensi kehilangan sedikit data di edge case.
Untuk panduan ini, kita fokus ke asynchronous streaming replication karena ini yang paling umum dipakai di production dan relatif gampang di-setup.
Persiapan Sebelum Setup
Oke, sebelum kita mulai ngoprek, siapkan dulu environment-nya. Kamu butuh:
- 2 buah server (bisa VM, VPS, atau bare metal) — kita sebut
node-1(primary) dannode-2(standby) - PostgreSQL terinstall di kedua server (aku pakai PostgreSQL 16, tapi panduan ini juga work untuk versi 14 ke atas)
- Koneksi jaringan antara kedua server (pastikan port 5432 bisa diakses)
- Sistem operasi Ubuntu 22.04 atau yang sejenis (aku pakai Ubuntu, kalau kamu pakai distro lain tinggal sesuaikan perintah package manager-nya)
Pastikan juga kedua server punya spesifikasi yang mirip. Nggak harus identik, tapi idealnya RAM dan CPU-nya sebanding. Kalau standby server jauh lebih lemot, performa failover bisa mengecewakan.
Pertama, install PostgreSQL di kedua server:
# Tambahkan repository PostgreSQL resmi
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
# Install PostgreSQL 16
sudo apt-get install postgresql-16 postgresql-client-16 -y
Setelah install, pastikan service-nya jalan:
sudo systemctl enable postgresql
sudo systemctl start postgresql
sudo systemctl status postgresql
Kalau status-nya active (running), berarti aman. Lanjut!
Step-by-Step Setup Streaming Replication
Ini bagian intinya. Aku akan jelaskan langkah per langkah, dan aku bakal kasih juga konfigurasi lengkapnya supaya kamu nggak bingung.
1. Konfigurasi Primary Server (node-1)
Di server primary, kita perlu mengubah beberapa parameter di postgresql.conf dan membuat user khusus untuk replicasi.
Buat user replicasi:
sudo -u postgres psql -c "CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'password_kuat_banget_123';"
Edit postgresql.conf:
sudo nano /etc/postgresql/16/main/postgresql.conf
Ubah atau tambahkan baris-baris berikut:
# Listener
listen_addresses = '*'
# WAL Settings untuk Replication
wal_level = replica
max_wal_senders = 5
wal_keep_size = '1GB'
# Archive (opsional tapi recommended)
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/archive/%f'
# Logging (biar gampang debug)
log_replication_commands = on
Penjelasan singkat:
wal_level = replica— ini wajib, tanpa ini replication nggak bisa jalan. Ini memberitahu PostgreSQL untuk menyimpan cukup informasi di WAL agar standby bisa ikut-ikutan.max_wal_senders = 5— berapa banyak standby yang bisa terhubung. 5 udah cukup buat kebanyakan kasus.wal_keep_size = 1GB— berapa banyak WAL yang disimpan di primary. Kalau standby sempat terputus, dia masih bisa catch up selama WAL-nya belum dihapus.archive_modedanarchive_command— opsional, tapi sangat disarankan. Ini bikin backup copy dari setiap WAL segment, jadi kalau WAL di primary terhapus sebelum standby sempat ambil, masih ada cadangan.
Buat direktori archive:
sudo mkdir -p /var/lib/postgresql/archive
sudo chown postgres:postgres /var/lib/postgresql/archive
Edit pg_hba.conf:
sudo nano /etc/postgresql/16/main/pg_hba.conf
Tambahkan baris ini di akhir file:
Ganti 192.168.1.102 dengan IP address server standby kamu. Kalau kamu mau lebih fleksibel, bisa pakai CIDR yang lebih besar, tapi untuk production lebih aman dibatasi per IP.
Restart PostgreSQL:
sudo systemctl restart postgresql
2. Setup Standby Server (node-2)
Di server standby, kita perlu mengambil base backup dari primary dan mengkonfigurasinya supaya dia tahu bahwa dirinya adalah standby.
Stop PostgreSQL dulu:
sudo systemctl stop postgresql
Backup data directory yang lama (jaga-jaga):
sudo mv /var/lib/postgresql/16/main /var/lib/postgresql/16/main.bak
Ambil base backup dari primary:
sudo -u postgres pg_basebackup -h 192.168.1.101 -U replicator -D /var/lib/postgresql/16/main -Fp -Xs -P -R
Penjelasan flag-nya:
-h 192.168.1.101— IP primary server-U replicator— user replicasi yang kita buat tadi-D— tujuan data directory-Fp— format plain (bukan tar)-Xs— streaming method buat mengambil WAL-P— show progress-R— ini penting! Flag ini otomatis membuat filestandby.signaldan mengisi connection info dipostgresql.auto.conf
Kalau perintah ini berhasil, kamu akan melihat progress bar dan data directory akan terisi. File standby.signal akan otomatis muncul di data directory — file ini yang memberitahu PostgreSQL bahwa instance ini harus jalan sebagai standby.
Verifikasi postgresql.auto.conf:
sudo -u postgres cat /var/lib/postgresql/16/main/postgresql.auto.conf
Harusnya ada baris seperti ini:
primary_conninfo = 'user=replicator password=password_kuat_banget_123 channel_binding=prefer host=192.168.1.101 port=5432 sslmode=prefer sslnegotiation=direct ...'
Pastikan izin file benar:
sudo chown -R postgres:postgres /var/lib/postgresql/16/main
sudo chmod 700 /var/lib/postgresql/16/main
Start PostgreSQL di standby:
sudo systemctl start postgresql
3. Verifikasi Replication Berjalan
Sekarang bagian yang paling seru — ngecek apakah replication-nya beneran jalan!
Di primary server (node-1):
sudo -u postgres psql -c "SELECT * FROM pg_stat_replication;"
Kalau berhasil, kamu akan melihat output seperti ini:
Kalau state-nya streaming, SELAMAT! Replication kamu sudah jalan. 🎉
Di standby server (node-2), cek status recovery:
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
Harusnya hasilnya t (true), yang artinya server ini sedang dalam mode recovery/standby.
Cek juga apakah data benar-benar ter-replicasi. Buat test table di primary:
# Di primary
sudo -u postgres psql -c "CREATE TABLE test_replication (id SERIAL PRIMARY KEY, nama VARCHAR(50));"
sudo -u postgres psql -c "INSERT INTO test_replication (nama) VALUES ('Hello dari primary!');"
Lalu cek di standby:
# Di standby
sudo -u postgres psql -c "SELECT * FROM test_replication;"
Harusnya data yang kamu insert di primary sudah muncul di standby. Keren kan?
4. Konfigurasi Tambahan yang Penting
Ada beberapa pengaturan tambahan yang sering dilupakan tapi sangat penting:
Streaming replication timeout (di primary postgresql.conf):
wal_sender_timeout = 60s
Recovery settings (di standby, bisa tambahkan di postgresql.conf):
hot_standby = on
hot_standby_feedback = on
max_standby_streaming_delay = 30s
max_standby_archive_delay = 60s
hot_standby = on memungkinkan standby server melayani read query. Ini sangat berguna buat read scaling — kamu bisa arahkan query SELECT ke standby supaya primary nggak kelebihan beban.
Automasi Failover dengan repmgr
Streaming replication tanpa automasi failover itu kayak punya ban serep tapi nggak bawa dongkrak. Kamu tahu backup-nya ada, tapi waktu kejadian, kamu masih harus setup manual.
Di sinilah repmgr (Replication Manager) berperan. repmgr adalah tool open source yang memudahkan manajemen PostgreSQL replication cluster. Dia bisa:
- Monitoring status replication secara real-time
- Automated failover — kalau primary mati, standby otomatis promote jadi primary
- Manual switchover — buat planned maintenance
- Rejoin — server lama yang sudah hidup lagi otomatis jadi standby
Install repmgr di kedua server:
sudo apt-get install postgresql-16-repmgr -y
Buat user dan database repmgr di primary:
CREATE USER repmgr SUPERUSER LOGIN PASSWORD 'repmgr_password_123';
CREATE DATABASE repmgr OWNER repmgr;
Buat file konfigurasi repmgr di kedua server:
sudo nano /etc/postgresql/16/main/repmgr.conf
Untuk primary (node-1):
node_id=1
node_name='node-1'
conninfo='host=192.168.1.101 user=repmgr dbname=repmgr password=repmgr_password_123'
data_directory='/var/lib/postgresql/16/main'
# Failover settings
failover='automatic'
promote_command='repmgr standby promote -f /etc/postgresql/16/main/repmgr.conf'
follow_command='repmgr standby follow -f /etc/postgresql/16/main/repmgr.conf --upstream-node-id=%n'
# Monitoring
monitoring_history=yes
monitor_interval_secs=5
# Log
log_level=INFO
log_file='/var/log/postgresql/repmgr.log'
Untuk standby (node-2):
node_id=2
node_name='node-2'
conninfo='host=192.168.1.102 user=repmgr dbname=repmgr password=repmgr_password_123'
data_directory='/var/lib/postgresql/16/main'
# Failover settings
failover='automatic'
promote_command='repmgr standby promote -f /etc/postgresql/16/main/repmgr.conf'
follow_command='repmgr standby follow -f /etc/postgresql/16/main/repmgr.conf --upstream-node-id=%n'
# Monitoring
monitoring_history=yes
monitor_interval_secs=5
# Log
log_level=INFO
log_file='/var/log/postgresql/repmgr.log'
Register primary node:
sudo -u postgres repmgr -f /etc/postgresql/16/main/repmgr.conf primary register
Register standby node (di node-2):
sudo -u postgres repmgr -f /etc/postgresql/16/main/repmgr.conf standby register
Cek cluster status:
sudo -u postgres repmgr -f /etc/postgresql/16/main/repmgr.conf cluster show
Output-nya kurang lebih seperti ini:
Jalankan repmgrd daemon di kedua server:
Edit /etc/postgresql/16/main/postgresql.conf:
shared_preload_libraries = 'repmgr'
Restart PostgreSQL, lalu jalankan repmgrd:
sudo systemctl restart postgresql
sudo systemctl enable repmgrd
sudo systemctl start repmgrd
Sekarang, kalau primary server mati, repmgr di node-2 akan mendeteksi kegagalan dan otomatis promote node-2 menjadi primary. Begitu node-1 hidup lagi, dia bisa di-rejoin sebagai standby.
Test failover:
# Di primary, stop PostgreSQL paksa
sudo systemctl stop postgresql
# Tunggu beberapa detik, lalu cek di node-2
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
# Harusnya sekarang 'f' karena node-2 sudah jadi primary
Tips dari Pengalaman: Hal yang Sering Terlewat
Setelah setup beberapa kali di production, ini beberapa pelajaran yang aku dapat:
1. Selalu test failover secara berkala. Jangan tunggu sampai ada kejadian baru baru tahu failover-nya nggak jalan. Jadwalkan failover test minimal sebulan sekali.
2. Monitoring adalah kunci. Pasang monitoring yang memantau replication lag. Kalau lag-nya terus membesar, ada masalah di jaringan atau beban primary terlalu berat. Kamu bisa pakai query ini:
-- Di standby, cek replication lag
SELECT
CASE
WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()
THEN 0
ELSE EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())
END AS replication_lag_seconds;
3. Jangan lupa firewall. Buka port 5432 (atau port custom kamu) dan port 5499 (default repmgr) antar node. Ini kesalahan klasik yang bikin debugging jadi lama.
4. Gunakan connection pooler. Setelah failover, aplikasi perlu tahu ke mana harus terhubung. Pakai PgBouncer atau HAProxy dengan script health check yang mendeteksi primary otomatis. Contoh HAProxy config:
5. Pertimbangkan synchronous replication kalau zero data loss adalah keharusan. Tapi ingat, synchronous replication bisa menambah latency pada setiap transaksi, dan kalau standby mati, primary juga bisa terhambat. Ada parameter synchronous_standby_names yang bisa dikonfigurasi dengan mode FIRST atau ANY untuk fleksibilitas lebih.
6. Backup tetap jalan. Replication bukan pengganti backup. Tetap ambil backup reguler (misalnya pakai pgBackRest), idealnya dari standby server supaya primary nggak terganggu.
7. Dokumentasikan prosedur failover. Kalau tim kamu lebih dari satu orang, tulis runbook yang jelas. Siapa yang bertanggung jawab, langkah-langkah apa yang harus dilakukan, dan bagaimana cara verify keberhasilan.
Kalau Cluster Kamu Butuh Lebih dari 2 Node
Dalam beberapa kasus, kamu mungkin butuh lebih dari satu standby. Misalnya satu standby buat HA, satu lagi buat read scaling atau reporting. PostgreSQL mendukung ini dari sananya — cukup jalankan pg_baseBackup ke server ketiga, keempat, dst.
Tapi perlu diingat: semua standby terhubung ke primary secara langsung (atau cascading replication). Semakin banyak standby, semakin besar beban di primary. Ini perlu dipertimbangkan dalam capacity planning.
Untuk cluster yang lebih besar dan kompleks, pertimbangkan juga tool seperti:
- Patroni — alternatif repmgr yang sangat populer, sering dipakai bersama etcd atau Consul untuk distributed consensus.
- Pgpool-II — connection pooler sekaligus load balancer yang bisa handle failover.
- Citus — kalau kamu butuh horizontal scaling (sharding) sekaligus HA.
Kalau kamu sudah sampai di sini, berarti kamu serius mau bikin database setup yang robust. Bagus banget! Tapi kalau kamu merasa setup ini terlalu ribet atau butuh bantuan profesional untuk mengkonfigurasi PostgreSQL replication di environment production kamu, jangan ragu untuk hubungi aku.
Kirim email ke [email protected] — aku bisa bantu dari assessment arsitektur, setup, sampai maintenance berkala. Lebih baik investasi waktu di awal daripada panik pas database tumbang di jam sibuk. 😉
FAQ (Frequently Asked Questions)
Apa bedanya streaming replication dan logical replication di PostgreSQL?
Streaming replication (juga disebut physical replication) menyalin seluruh cluster database secara byte-for-byte dari primary ke standby. Cocok untuk HA karena standby adalah identik dengan primary. Logical replication lebih granular — kamu bisa replicasi per-tabel atau bahkan filter data tertentu. Logical replication lebih fleksibel tapi nggak ideal untuk failover otomatis karena schema dan konfigurasi server nggak ikut ter-replicasi. Untuk keperluan high availability, pakai streaming replication. Untuk migrasi data partial atau integrasi antar sistem, pakai logical replication.
Berapa besar replication lag yang normal?
Dalam kondisi jaringan yang sehat dan beban yang wajar, lag biasanya cuma beberapa milidetik sampai 1-2 detik untuk asynchronous replication. Kalau lag-nya terus di atas 5-10 detik, ada masalah yang perlu diinvestigasi — bisa jadi jaringan, I/O disk di standby, atau beban primary yang terlalu tinggi. Kamu bisa monitor lag dengan query pg_last_xact_replay_timestamp() di standby atau melalui kolom replay_lag di pg_stat_replication di primary (tersedia mulai PostgreSQL 14).
Bisakah PostgreSQL replication jalan di antara versi yang berbeda?
Streaming replication mengharuskan versi PostgreSQL yang sama di primary dan standby. Kamu nggak bisa punya primary di PostgreSQL 16 dan standby di PostgreSQL 14 — ini nggak akan work. Namun, untuk upgrade major version, ada strategi yang disebut pg_upgrade dengan standby, atau kamu bisa pakai logical replication sebagai jembatan migrasi antar versi. Kalau mau upgrade, langkah yang paling aman adalah upgrade standby duluan, lalu lakukan switchover.
Bagaimana cara handle split-brain dalam PostgreSQL HA?
Split-brain terjadi ketika dua server berpikir keduanya adalah primary. Ini bisa terjadi kalau jaringan antara primary dan standby terputus tapi primary masih melayani aplikasi. Untuk menghindari ini: gunakan witness server atau consul/etcd sebagai tie-breaker, konfigurasi fencing (STONITH) untuk mematikan node lama secara paksa saat failover, dan pastikan pg_hba.conf di standby menolak koneksi write saat dia dalam recovery mode. repmgr juga punya mekanisme built-in untuk meminimalkan risiko split-brain.