PostgreSQL Streaming Replication Master-Replica บน VPS

PostgreSQL Streaming Replication คือกลไกที่ช่วยให้ข้อมูลในฐานข้อมูล Master ถูกคัดลอกไปยัง Replica Server แบบ Real-time ผ่าน WAL (Write-Ahead Log) ช่วยให้ระบบมี High Availability และรองรับ Read Scaling ได้โดยกระจาย Query ไปยัง Replica บทความนี้จะแนะนำการตั้งค่าบน VPS Ubuntu 2 เครื่องทีละขั้นตอน

Streaming Replication คืออะไร และทำงานอย่างไร

PostgreSQL ใช้ WAL (Write-Ahead Log) เป็นกลไกหลักในการบันทึกทุกการเปลี่ยนแปลงข้อมูลก่อนที่จะ Apply จริง Streaming Replication ส่ง WAL record ไปยัง Replica แบบต่อเนื่อง ทำให้ Replica อยู่ในสถานะ Hot Standby พร้อมรับ Read Query ได้ตลอดเวลา

ข้อควรรู้: Streaming Replication ของ PostgreSQL เป็น Asynchronous โดยค่าเริ่มต้น หมายความว่า Transaction ที่ Commit บน Master อาจยังไม่ถึง Replica ทันที ถ้าต้องการ Synchronous ให้ตั้งค่า synchronous_commit = on และระบุ synchronous_standby_names

สิ่งที่ต้องเตรียมก่อนเริ่ม

ติดตั้ง PostgreSQL บนทั้ง 2 เครื่อง

# รันบนทั้ง Master และ Replica
sudo apt update
sudo apt install -y postgresql postgresql-contrib

# ตรวจสอบ version
psql --version

# เปิดใช้งานและ Start service
sudo systemctl enable postgresql
sudo systemctl start postgresql
sudo systemctl status postgresql

ตั้งค่า Master Server

แก้ไข postgresql.conf บน Master

# เปิดไฟล์ config
sudo nano /etc/postgresql/15/main/postgresql.conf

แก้หรือเพิ่มค่าต่อไปนี้:

listen_addresses = '*'
wal_level = replica
max_wal_senders = 5
wal_keep_size = 256MB
hot_standby = on

แก้ไข pg_hba.conf บน Master

sudo nano /etc/postgresql/15/main/pg_hba.conf

เพิ่มบรรทัดนี้ที่ท้ายไฟล์ (แทน 10.0.0.2 ด้วย IP จริงของ Replica):

host    replication     replicator      10.0.0.2/32     scram-sha-256

สร้าง Replication User บน Master

sudo -u postgres psql
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'StrongPass123!';
\q

Restart PostgreSQL บน Master

sudo systemctl restart postgresql

ตั้งค่า Replica Server

หยุด PostgreSQL และลบ Data Directory บน Replica

sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/15/main/*

ทำ Base Backup จาก Master

# รันบน Replica (แทน 10.0.0.1 ด้วย IP จริงของ Master)
sudo -u postgres pg_basebackup \
  -h 10.0.0.1 \
  -U replicator \
  -D /var/lib/postgresql/15/main \
  -P -Xs -R

# -P = แสดง progress
# -Xs = streaming WAL ระหว่าง backup
# -R = สร้าง standby.signal และ recovery configuration อัตโนมัติ

ระบบจะถามรหัสผ่านของ replicator ให้ใส่ StrongPass123!

ตรวจสอบไฟล์ที่สร้างขึ้น

# ตรวจว่ามี standby.signal
ls /var/lib/postgresql/15/main/standby.signal

# ตรวจ primary_conninfo ใน postgresql.auto.conf
sudo cat /var/lib/postgresql/15/main/postgresql.auto.conf

Start PostgreSQL บน Replica

sudo systemctl start postgresql
sudo systemctl status postgresql

ตรวจสอบสถานะ Replication

ตรวจบน Master

sudo -u postgres psql -c "SELECT * FROM pg_stat_replication;"

ถ้า Replication ทำงานปกติ จะเห็น row ที่มี state = streaming และ sent_lsn กับ replay_lsn ใกล้เคียงกัน

ตรวจบน Replica

sudo -u postgres psql -c "SELECT * FROM pg_stat_wal_receiver;"

ทดสอบ Replication

# สร้าง Table บน Master
sudo -u postgres psql
CREATE TABLE test_rep (id serial, msg text);
INSERT INTO test_rep (msg) VALUES ('Hello from Master');
\q

# ตรวจบน Replica
sudo -u postgres psql
SELECT * FROM test_rep;
\q

เคล็ดลับ Monitor Lag: ใช้คำสั่ง SELECT now() - pg_last_xact_replay_timestamp() AS replication_lag; บน Replica เพื่อดูว่า Replication ช้ากว่า Master กี่วินาที ถ้า lag เริ่มสูง อาจเกิดจาก Network หรือ Replica รับ Query หนักเกินไป

การใช้ Replica สำหรับ Read Queries

ใน Application สามารถส่ง Read Query ไปยัง Replica IP ได้โดยตรง เพื่อลดโหลดบน Master เช่น ใน PHP ใช้ Connection Pool ที่แยก Write กับ Read:

// Write connection (Master)
$dbWrite = new PDO('pgsql:host=10.0.0.1;dbname=myapp', 'appuser', 'pass');

// Read connection (Replica)
$dbRead = new PDO('pgsql:host=10.0.0.2;dbname=myapp', 'appuser', 'pass');

ข้อควรระวัง: อย่าส่ง Write Query ไปยัง Replica เพราะจะ Error เนื่องจาก Replica อยู่ใน Read-Only mode

การทำ Failover เมื่อ Master ล้มเหลว

เมื่อ Master Server ไม่สามารถให้บริการได้ สามารถ Promote Replica ให้เป็น Master ใหม่ได้ด้วยคำสั่ง:

# Promote Replica ให้กลายเป็น Master ใหม่ (รันบน Replica)
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/15/main

# ตรวจสอบว่า Replica เปลี่ยนเป็น Primary แล้ว
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
# ผลลัพธ์ควรเป็น false (แปลว่าเป็น Primary แล้ว)

หลังจาก Promote แล้ว ให้อัปเดต Connection String ในแอปพลิเคชันทั้งหมดให้ชี้ไปยัง IP ของ Replica ที่กลายเป็น Master ใหม่ และหากต้องการนำ Master เดิมกลับมาให้ติดตั้งใหม่เป็น Replica ของ Primary ตัวใหม่

Failover อัตโนมัติ: สำหรับระบบ Production ที่ต้องการ Failover อัตโนมัติแนะนำให้ใช้เครื่องมือเช่น Patroni หรือ repmgr ซึ่งจัดการ Leader Election และ Failover ให้โดยอัตโนมัติ ลด Downtime เหลือน้อยที่สุด

เปรียบเทียบ Replication Mode ต่างๆ ใน PostgreSQL

PostgreSQL รองรับ Replication หลายรูปแบบ แต่ละแบบเหมาะกับ Use Case ต่างกัน

Mode ลักษณะ ข้อดี เหมาะกับ
Streaming (Async) WAL ส่งแบบ near real-time ไม่รอ Replica ยืนยัน ประสิทธิภาพสูง Latency ต่ำบน Master Read Scaling ทั่วไป
Streaming (Sync) Master รอ Replica ยืนยัน WAL ก่อน Commit ไม่มี Data Loss เลย (RPO=0) ระบบการเงิน ข้อมูลสำคัญ
Logical Replication Replicate เฉพาะบาง Table หรือบาง Database ยืดหยุ่น รองรับ PostgreSQL ต่าง version Migration ข้าม version
Cascading Replication Replica ส่ง WAL ต่อให้ Replica อื่นอีกทอด ลดโหลดบน Primary Replica หลายสาขาต่างพื้นที่

Backup และ Point-in-Time Recovery (PITR) ร่วมกับ Replication

Replication ไม่ใช่ Backup — หากลบข้อมูลบน Master โดยไม่ตั้งใจ การเปลี่ยนแปลงนั้นจะถูกส่งไปยัง Replica ทันที ดังนั้นควรใช้ WAL Archiving ร่วมกันเพื่อรองรับ PITR

# เพิ่มใน postgresql.conf บน Master เพื่อ Archive WAL
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal-archive/%f'

เมื่อมี WAL Archive สามารถกู้คืนฐานข้อมูลไปยัง Point in Time ใดก็ได้ เช่น ย้อนกลับก่อนที่จะมีการลบข้อมูลผิดพลาด โดยระบุ recovery_target_time ใน recovery.conf หรือ postgresql.auto.conf

ปัญหาที่พบบ่อยและวิธีแก้ไข

ต่อไปนี้คือปัญหาที่พบบ่อยในการตั้งค่า Streaming Replication พร้อมวิธีแก้ไข

Replica ไม่เชื่อมต่อ Master

ตรวจสอบว่า pg_hba.conf บน Master มี IP ของ Replica และใช้ auth method ที่ถูกต้อง และ Firewall/Security Group เปิด Port 5432 ให้ IP ของ Replica

# ทดสอบการเชื่อมต่อจาก Replica ไปยัง Master
psql -h 10.0.0.1 -U replicator -d postgres

Replication Lag สูงผิดปกติ

Lag สูงอาจเกิดจาก Network bottleneck หรือ Replica รับ Read Query หนักเกินไป ตรวจสอบด้วย:

# บน Master: ดู Lag ของแต่ละ Replica
SELECT client_addr, state,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS lag_bytes
FROM pg_stat_replication;

Disk เต็มบน Master เพราะ WAL สะสม

หาก Replica ไม่เชื่อมต่อนานๆ WAL จะสะสมบน Master ตั้งค่า wal_keep_size ให้เหมาะสม หรือใช้ Replication Slot แทนเพื่อให้ Master รู้ว่าต้องเก็บ WAL ถึงจุดไหน

คำแนะนำสำหรับ Production: ทดสอบ Failover ใน Staging Environment ก่อนนำไปใช้งานจริงเสมอ และมีแผน Runbook ที่ชัดเจนสำหรับทีมงานเมื่อเกิดเหตุฉุกเฉิน

การเลือก VPS ที่เหมาะกับ PostgreSQL Replication

ประสิทธิภาพของ Streaming Replication ขึ้นอยู่กับ Spec ของ VPS ทั้ง 2 เครื่องโดยตรง โดยเฉพาะ Network Bandwidth และ Disk I/O ที่ส่งผลต่อ Replication Lag

Spec Development Production (ปานกลาง) Production (สูง)
RAM 2 GB 4–8 GB 16+ GB
Disk 50 GB SSD 100–200 GB NVMe 500+ GB NVMe
shared_buffers 256 MB 1–2 GB 4+ GB
wal_keep_size 64 MB 256 MB 512+ MB

การ Monitor ระบบ Replication อย่างต่อเนื่อง

ระบบ Replication ที่ดีต้องมี Monitoring ที่แจ้งเตือนก่อนเกิดปัญหา โดยมีตัวชี้วัดหลักที่ต้องติดตาม ดังนี้

ตัวชี้วัดสำคัญที่ต้อง Monitor

# Query รวมสำหรับ Dashboard Monitoring
SELECT
  client_addr AS replica_ip,
  state,
  pg_wal_lsn_diff(sent_lsn, write_lsn) AS write_lag_bytes,
  pg_wal_lsn_diff(sent_lsn, flush_lsn) AS flush_lag_bytes,
  pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes,
  sync_state
FROM pg_stat_replication;

สามารถตั้ง Alert ด้วย Prometheus + postgres_exporter + Grafana เพื่อแจ้งเตือนทาง email หรือ LINE เมื่อ Replication Lag เกินค่าที่กำหนด ทำให้ทีมงานรับรู้ปัญหาก่อนที่ผู้ใช้จะเจอ

สิ่งที่ต้องทำหลังตั้งค่า Replication เสร็จ

การตั้งค่า Replication สำเร็จเพียงขั้นแรกเท่านั้น ยังมีงานสำคัญที่ต้องทำก่อนนำระบบขึ้น Production จริง

การลงทุนเวลาเตรียมการเหล่านี้ตั้งแต่ต้น จะช่วยลด Downtime จริงเมื่อเกิดเหตุฉุกเฉิน และทำให้ทีมงานมั่นใจในระบบที่ดูแลอยู่มากขึ้น ระบบ Replication ที่ดีวัดได้ที่ความเร็วในการกู้คืน ไม่ใช่แค่ความเร็วในการ Replicate

ต้องการ VPS สำหรับระบบฐานข้อมูล?

VPS Linux Ubuntu เริ่มต้น 500 บาท/เดือน พร้อม Full Root Access, SSD และ Uptime 99% เหมาะสำหรับ PostgreSQL, MySQL และระบบฐานข้อมูลทุกประเภท

ดูแพ็กเกจ VPS