ทำ Streaming Replication บน PostgreSQL
Streaming Replication ของ PostgreSQL ส่งข้อมูล WAL จากตัวหลักไปยังตัวสำรองแบบต่อเนื่อง ทำให้มีสำเนาที่ตามหลังเพียงเสี้ยววินาที ตัวสำรองยังรับงานอ่านได้ด้วย จึงช่วยแบ่งเบาภาระของตัวหลักไปพร้อมกัน
คู่มือนี้ตั้งค่าตั้งแต่ศูนย์ด้วย pg_basebackup ซึ่งเป็นวิธีมาตรฐานที่คัดลอกข้อมูลตั้งต้นและตั้งค่าให้พร้อมในคำสั่งเดียว
สิ่งที่ต้องเตรียม
- เซิร์ฟเวอร์สองเครื่องที่ติดตั้ง PostgreSQL เวอร์ชันหลักเดียวกัน
- เครือข่ายภายในระหว่างกัน และพื้นที่ดิสก์บนตัวสำรองไม่น้อยกว่าตัวหลัก
ในคู่มือนี้ตัวหลักคือ 10.0.0.41 และตัวสำรองคือ 10.0.0.42
ขั้นตอนที่ 1: ตั้งค่าตัวหลัก
sudo nano /etc/postgresql/16/main/postgresql.conf
listen_addresses = '10.0.0.41,localhost'
wal_level = replica
max_wal_senders = 10
wal_keep_size = 2GB
archive_mode = on
archive_command = 'test ! -f /var/lib/postgresql/archive/%f && cp %p /var/lib/postgresql/archive/%f'
# ให้ตัวสำรองรายงานตำแหน่งกลับมา ทำให้ดูความล่าช้าได้
hot_standby_feedback = on
sudo mkdir -p /var/lib/postgresql/archive
sudo chown postgres:postgres /var/lib/postgresql/archive
wal_keep_size คือปริมาณ WAL ที่เก็บไว้เผื่อตัวสำรองตามไม่ทัน หากตั้งน้อยเกินไปและตัวสำรองหลุดไปนาน จะต้องสร้างใหม่ทั้งหมด วิธีที่ดีกว่าคือใช้ Replication Slot ตามขั้นตอนที่ 3
ขั้นตอนที่ 2: สร้างผู้ใช้และอนุญาตการเชื่อมต่อ
sudo -u postgres psql
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'รหัสผ่านที่ยาวและสุ่ม';
SELECT rolname, rolreplication FROM pg_roles WHERE rolname = 'replicator';
sudo nano /etc/postgresql/16/main/pg_hba.conf
host replication replicator 10.0.0.42/32 scram-sha-256
sudo systemctl restart postgresql
sudo -u postgres psql -c "SHOW wal_level;"
ขั้นตอนที่ 3: สร้าง Replication Slot
Slot ทำให้ตัวหลักเก็บ WAL ไว้จนกว่าตัวสำรองจะรับไปแล้วจริง ป้องกันปัญหาตัวสำรองตามไม่ทันแล้วต้องสร้างใหม่
sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('standby1');"
sudo -u postgres psql -c "SELECT slot_name, active, restart_lsn FROM pg_replication_slots;"
ข้อควรระวัง หากตัวสำรองหายไปถาวรแต่ Slot ยังอยู่ ตัวหลักจะเก็บ WAL ไว้เรื่อย ๆ จนดิสก์เต็ม ต้องลบ Slot ทิ้งด้วย SELECT pg_drop_replication_slot('standby1');
ขั้นตอนที่ 4: สร้างตัวสำรองด้วย pg_basebackup
# บนตัวสำรอง หยุดบริการและล้างข้อมูลเดิม
sudo systemctl stop postgresql
sudo -u postgres rm -rf /var/lib/postgresql/16/main/*
sudo -u postgres pg_basebackup \
-h 10.0.0.41 -p 5432 -U replicator \
-D /var/lib/postgresql/16/main \
-Fp -Xs -P -R \
-S standby1
ความหมายของตัวเลือก -Fp คือเขียนเป็นไฟล์ปกติ -Xs คือรับ WAL ไปพร้อมกันระหว่างคัดลอก -P คือแสดงความคืบหน้า -R คือสร้างไฟล์ตั้งค่าการเชื่อมต่อให้อัตโนมัติ และ -S คือใช้ Slot ที่สร้างไว้
ตรวจว่าไฟล์ที่ต้องมีถูกสร้างแล้ว
sudo ls -l /var/lib/postgresql/16/main/standby.signal
sudo cat /var/lib/postgresql/16/main/postgresql.auto.conf
ขั้นตอนที่ 5: เริ่มตัวสำรอง
sudo nano /etc/postgresql/16/main/postgresql.conf
hot_standby = on
listen_addresses = '10.0.0.42,localhost'
sudo systemctl start postgresql
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
ผลควรเป็น t ซึ่งแปลว่าอยู่ในโหมดตัวสำรองและกำลังรับข้อมูลอยู่
ขั้นตอนที่ 6: ตรวจสอบสถานะและความล่าช้า
-- บนตัวหลัก
SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn,
write_lag, flush_lag, replay_lag, sync_state
FROM pg_stat_replication;
-- บนตัวสำรอง ดูว่าตามหลังกี่วินาที
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 lag_seconds;
ทดสอบจริง
# บนตัวหลัก
sudo -u postgres psql -c "CREATE TABLE IF NOT EXISTS repltest (id serial, t timestamptz DEFAULT now());"
sudo -u postgres psql -c "INSERT INTO repltest DEFAULT VALUES;"
# บนตัวสำรอง
sudo -u postgres psql -c "SELECT * FROM repltest ORDER BY id DESC LIMIT 5;"
ลองเขียนบนตัวสำรองเพื่อยืนยันว่าถูกปฏิเสธ
sudo -u postgres psql -c "INSERT INTO repltest DEFAULT VALUES;"
# ควรได้ ERROR: cannot execute INSERT in a read-only transaction
ขั้นตอนที่ 7: ใช้ตัวสำรองรับงานอ่าน
ชี้แอปส่วนที่อ่านอย่างเดียว เช่น หน้ารายงาน มาที่ตัวสำรอง ลดภาระตัวหลักได้มาก
ข้อควรระวังคือความล่าช้า ข้อมูลที่เพิ่งเขียนอาจยังไม่ปรากฏบนตัวสำรองทันที จึงไม่เหมาะกับหน้าที่ต้องอ่านข้อมูลที่เพิ่งบันทึกไป เช่น หน้ายืนยันคำสั่งซื้อ
หากต้องการให้ตัวสำรองยืนยันก่อนตัวหลักตอบว่าสำเร็จ ตั้งเป็นแบบซิงโครนัส
# บนตัวหลัก
synchronous_standby_names = 'standby1'
synchronous_commit = on
วิธีนี้ทำให้ไม่มีข้อมูลสูญหายเลยเมื่อตัวหลักล่ม แต่การเขียนจะช้าลงและหากตัวสำรองล่ม การเขียนบนตัวหลักจะหยุดรอ ต้องมีตัวสำรองอย่างน้อยสองตัวจึงจะใช้โหมดนี้ได้อย่างปลอดภัย
ขั้นตอนที่ 8: สลับตัวสำรองเป็นตัวหลัก
# บนตัวสำรอง
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/16/main
# หรือ
sudo -u postgres psql -c "SELECT pg_promote();"
sudo -u postgres psql -c "SELECT pg_is_in_recovery();" # ควรเป็น f
หลังสลับแล้ว เครื่องเดิมจะกลับมาเป็นตัวสำรองของเครื่องใหม่ไม่ได้ทันที ต้องใช้ pg_rewind ปรับให้ตรงกันก่อน
sudo systemctl stop postgresql
sudo -u postgres pg_rewind \
--target-pgdata=/var/lib/postgresql/16/main \
--source-server="host=10.0.0.42 user=replicator password=xxx" \
--progress
ปัญหาที่พบบ่อย
pg_basebackup ล้มเหลวเรื่องการยืนยันตัวตน
ตรวจว่า pg_hba.conf มีบรรทัดสำหรับฐานข้อมูลชื่อ replication ซึ่งเป็นคำสงวน ไม่ใช่ชื่อฐานข้อมูลจริง และรีโหลดคอนฟิกแล้วด้วย sudo -u postgres psql -c "SELECT pg_reload_conf();"
ตัวสำรองตามไม่ทันจนหลุด
ใช้ Replication Slot ตามขั้นตอนที่ 3 และตรวจว่าดิสก์ของตัวสำรองไม่ช้ากว่าตัวหลัก ดูข้อความ requested WAL segment has already been removed ใน Log ซึ่งยืนยันอาการนี้
ดิสก์ตัวหลักเต็มเพราะ WAL
ตรวจ Slot ที่ไม่มีการใช้งานด้วย SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) FROM pg_replication_slots; Slot ที่ active เป็น false และค้างมานานคือสาเหตุ ให้ลบทิ้ง
Query บนตัวสำรองถูกยกเลิก
เกิดเมื่อการเปลี่ยนแปลงจากตัวหลักขัดกับ Query ที่รันอยู่ ตั้ง max_standby_streaming_delay ให้ยาวขึ้น หรือเปิด hot_standby_feedback = on ซึ่งบอกตัวหลักไม่ให้ลบข้อมูลที่ตัวสำรองยังใช้อยู่
ต้องการวางระบบฐานข้อมูลพร้อม DR Site ในประเทศไทย ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/
- Categories:
- Cloud
- Tags:
- Cloud
- Cloud Server
หมวดหมู่ที่น่าสนใจ
- Account Settings
- AD Server
- AI
- Alibaba Cloud
- Anti-Spam Gateway
- AWS Amazon Web Services
- Campaign
- CentOS/AlmaLinux
- Cloud
- Cloud Backup
- Cloud Communication
- Cloud Migration
- Cloud Security
- Cloud Server Management
- Cloud Solution
- Cloud Solution for Government
- Cloud Solutions by Industry
- Cloud Storage
- Cloud VPS App Plus +
- Cloud VPS DirectAdmin
- Cloud VPS Plesk
- CSR
- Cyber Security
- Cybersecurity
- Data Sovereignty
- Database Server
- DDoS
- Digital Tranformation
- Digital Transformation
- Direct Mail
- Directadmin
- Domainname
- Ecommerce
- ERP
- Generative AI
- Getting Started
- Google Cloud
- Google G Suite
- Huawei Cloud
- IT News
- Linux Server
- Managed Cloud Services
- Managed Service Provider
- Manual
- Microsoft
- Microsoft 365
- Microsoft Azure
- News
- On-premise
- Private Mail Server
- Promotion
- Recommend Solution (Enterprise)
- Server
- Sovereign Cloud
- THAI DATA CLOUD Platform
- Ubuntu
- Ubuntu
- Uncategorized
- VMware
- VPS Server
- Web Design
- Web Hosting
- Web Hosting (DirectAdmin)
- Web Hosting (Plesk)
- Web Technologies
- Windows Server
- Wordpress
- Zimbra
- เรื่องราวความประทับใจ
- โซลูชันสำหรับธุรกิจการผลิตและยานยนต์
- โซลูชันสำหรับธุรกิจการศึกษา
- โซลูชันสำหรับธุรกิจการเงิน
- โซลูชันสำหรับธุรกิจขนส่งและกระจายสินค้า
- โซลูชันสำหรับธุรกิจค้าปลีก
- โซลูชันสำหรับธุรกิจท่องเที่ยว
- โซลูชันสำหรับธุรกิจบริการสุขภาพและโรงพยาบาล
- โซลูชันสำหรับธุรกิจประกันภัย
- โซลูชันสำหรับธุรกิจพลังงานและสาธารณูปโภค
- โซลูชันสำหรับธุรกิจสื่อสารมวลชนและเอ็นเตอร์เทนเมนท์
- โซลูชันสำหรับธุรกิจอสังหาริมทรัพย์
- โซลูชันสำหรับธุรกิจเทคโนโลยี








