ตั้งค่า MariaDB Galera Cluster หลายโหนด High Availability

เว็บไซต์ใหญ่ที่ต้องการ High Availability ต้องไม่พึ่ง Database เครื่องเดียว — Galera Cluster ทำให้ MariaDB ทำงานเป็น Synchronous Multi-Master หลายโหนด: เครื่องไหนตาย เครื่องอื่นรับงานต่อทันที โดยข้อมูล เหมือนกันทุกโหนดในเวลาจริง

คู่มือนี้พาตั้ง Galera Cluster 3 โหนดบน Ubuntu 22.04 ตั้งแต่ติดตั้ง MariaDB, แก้ galera.cnf, bootstrap node แรก, ไปจน join node อื่น พร้อมวิธีตรวจ cluster health และทดสอบ Failover

ต้องเตรียม: VPS Ubuntu 22.04 จำนวน 3 เครื่อง (Galera ต้องการ odd number ขั้นต่ำ 3 — กัน split-brain), RAM 2GB+ ต่อโหนด, Network เร็ว ping ระหว่างโหนดต่ำ < 5ms ในเครือข่ายเดียวกัน

Galera Cluster คืออะไร

Galera คือ replication library ที่ทำให้ MariaDB / MySQL หลายโหนดเป็น Active-Active — เขียนได้ทุกโหนด, ทุกการ COMMIT จะถูก replicate ไปทุกโหนดก่อน finalize (synchronous) ดังนั้น ข้อมูลตรงกัน 100% ไม่มี replication lag เหมือน Master-Slave

Galera vs Master-Slave Replication

หัวข้อGaleraMaster-Slave
ReplicationSynchronous (sync ก่อน commit)Asynchronous (delay บาง ms)
Writeเขียนได้ทุก nodeเขียนได้แค่ Master
Failoverอัตโนมัติทันทีต้อง promote slave
Data Consistency100% เหมือนกันมี lag
เหมาะกับHA, e-commerce, sticky sessionRead-heavy, reporting, analytics

Topology — 3 โหนดต้องเตรียมอะไร

สมมุติเรามี 3 VPS:

ทุกโหนดต้องเปิด Port: 3306 (MariaDB client), 4567 (Galera replication), 4568 (IST), 4444 (SST)

ขั้นที่ 1 — ติดตั้ง MariaDB บนทุกโหนด

รันคำสั่งต่อไปนี้ ทั้ง 3 เครื่อง:

sudo apt update
sudo apt install -y mariadb-server galera-4
sudo systemctl stop mariadb

ตรวจสอบเวอร์ชัน (ควรเป็น 10.6 ขึ้นไป):

mariadb --version

ขั้นที่ 2 — แก้ /etc/mysql/mariadb.conf.d/60-galera.cnf บนทุกโหนด

สร้างไฟล์ใหม่ (ทุกโหนด):

sudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf

ใส่เนื้อหา (เปลี่ยน wsrep_node_address เป็น IP ของโหนดนั้นๆ):

[galera]
wsrep_on                 = ON
wsrep_provider           = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_address    = gcomm://10.0.0.11,10.0.0.12,10.0.0.13
wsrep_cluster_name       = "asiagb_cluster"
wsrep_node_address       = 10.0.0.11   # เปลี่ยนตามโหนด
wsrep_node_name          = "node1"     # เปลี่ยนตามโหนด
wsrep_sst_method         = rsync
binlog_format            = row
default_storage_engine   = InnoDB
innodb_autoinc_lock_mode = 2
bind-address             = 0.0.0.0

ขั้นที่ 3 — Bootstrap Node แรก (node1)

โหนดแรกที่เปิด Cluster ใช้คำสั่งพิเศษ galera_new_cluster:

sudo galera_new_cluster

ตรวจสถานะ:

sudo mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"

ผลควรเป็น wsrep_cluster_size = 1 เพราะตอนนี้มีโหนดเดียว

ขั้นที่ 4 — Join node2 และ node3

บน node2 และ node3 รัน:

sudo systemctl start mariadb

กลับมาที่ node1 ตรวจอีกครั้ง:

sudo mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"

ตอนนี้ควรเป็น wsrep_cluster_size = 3 แสดงว่าทั้ง 3 โหนดอยู่ใน cluster แล้ว

ขั้นที่ 5 — ทดสอบ Replication

บน node1:

sudo mysql -e "CREATE DATABASE galera_test;"
sudo mysql -e "CREATE TABLE galera_test.t1 (id INT PRIMARY KEY, name VARCHAR(50));"
sudo mysql -e "INSERT INTO galera_test.t1 VALUES (1, 'hello from node1');"

บน node2 หรือ node3 ตรวจ:

sudo mysql -e "SELECT * FROM galera_test.t1;"

ควรเห็นข้อมูลทันที (ไม่มี delay) — แสดงว่า cluster ทำงาน

ขั้นที่ 6 — ตรวจสุขภาพ Cluster

sudo mysql -e "SHOW STATUS LIKE 'wsrep_%';" | grep -E "cluster_size|cluster_status|connected|ready|local_state"

ค่าที่ต้องดู:

ตั้งค่า HAProxy หน้า Galera Cluster

แอปพลิเคชันควรต่อผ่าน HAProxy แทนการชี้ตรงไปโหนดใดโหนดหนึ่ง เพื่อให้ Failover โปร่งใสและกระจาย Write Load ได้สมดุล

ติดตั้ง HAProxy บนเครื่อง Load Balancer แยก (หรือโหนดใดโหนดหนึ่ง):

sudo apt install haproxy -y

เพิ่ม backend ใน /etc/haproxy/haproxy.cfg:

frontend mysql_front
    bind *:3306
    mode tcp
    default_backend mysql_cluster

backend mysql_cluster
    mode tcp
    balance leastconn
    option mysql-check user haproxy_check
    server node1 10.0.0.11:3306 check
    server node2 10.0.0.12:3306 check
    server node3 10.0.0.13:3306 check

สร้าง user ที่ HAProxy ใช้ตรวจ health บน node1:

sudo mysql -e "CREATE USER 'haproxy_check'@'%';"
sudo mysql -e "FLUSH PRIVILEGES;"

รีสตาร์ท HAProxy และตรวจสถานะ:

sudo systemctl restart haproxy
sudo systemctl status haproxy

ทำไมต้อง leastconn? Galera ใช้ synchronous write lock — โหนดที่ queue ว่างที่สุดรับ connection ใหม่ดีกว่า round-robin ซึ่งอาจส่งไปโหนดที่กำลัง commit transaction หนัก

การสำรองข้อมูล Galera Cluster ด้วย Mariabackup

Galera ไม่ใช่ระบบสำรอง — ถ้า DROP TABLE ถูกรันที่โหนดใด ข้อมูลจะหายทุกโหนดทันที ต้องมี Backup แยกต่างหาก วิธีที่แนะนำคือ Mariabackup (fork ของ Percona XtraBackup) ที่ทำ Hot Backup โดยไม่หยุด Cluster:

sudo apt install mariadb-backup -y

รัน Backup บนโหนดที่ต้องการ (ควรเลือกโหนดที่ load เบาที่สุด):

sudo mariabackup --backup \
    --target-dir=/var/backup/galera/$(date +%Y%m%d) \
    --user=root

Prepare Backup ก่อน Restore:

sudo mariabackup --prepare \
    --target-dir=/var/backup/galera/20260608

⚠️ ข้อควรระวัง: เมื่อ Restore ต้องหยุด MariaDB ก่อน แล้ว rsync backup dir ไปยัง /var/lib/mysql/ จากนั้น Bootstrap cluster ใหม่จากโหนดที่ Restore — ห้าม Restore ขณะ Cluster กำลังทำงานปกติเพราะ SST จะ overwrite ข้อมูลที่ Restore

วิธีสำรองข้อมูลข้อดีข้อจำกัด
Mariabackup (Hot)ไม่หยุด cluster, รองรับ InnoDB สมบูรณ์ไฟล์ขนาดใหญ่
mysqldumpไฟล์ SQL อ่านได้, Restore ง่ายช้ากับ DB ขนาดใหญ่
Snapshot (Cloud)Restore VM ทั้ง node ได้เร็วต้อง Crash-recovery ก่อน bootstrap

Monitor Galera Cluster ด้วย Prometheus + mysqld_exporter

การ monitor ที่ดีทำให้รู้ล่วงหน้าก่อนที่ cluster จะมีปัญหา ติดตั้ง mysqld_exporter บนทุกโหนด แล้วให้ Prometheus scrape metrics เหล่านี้:

ตัวอย่าง Prometheus alert rule ที่ควรมี:

- alert: GaleraClusterNodeMissing
  expr: mysql_global_status_wsrep_cluster_size < 3
  for: 1m
  labels:
    severity: critical
  annotations:
    summary: "Galera node count dropped below 3"

- alert: GaleraNodeNotReady
  expr: mysql_global_status_wsrep_ready == 0
  for: 30s
  labels:
    severity: critical
  annotations:
    summary: "Galera node not ready on {{ $labels.instance }}"

ถ้ายังไม่มี Prometheus สามารถใช้ Netdata ที่ติดตั้งง่ายและมี Galera plugin ในตัว:

wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
sh /tmp/netdata-kickstart.sh

เคล็ดลับสำคัญ — กัน Split-Brain

⚠️ ห้ามใช้ 2 โหนด — Galera ต้องการ odd number (3, 5, 7) ถ้าใช้ 2 และโหนดใดโหนดหนึ่งล่ม cluster ทั้งหมดจะ read-only ทันที (quorum หาย) ใช้ 3 เป็นต้นไปเสมอ

เมื่อ cluster ทั้งหมดดับพร้อมกัน — เปิดด้วย galera_new_cluster เฉพาะโหนดที่มี seqno สูงสุดเท่านั้น ตรวจได้ที่:

sudo cat /var/lib/mysql/grastate.dat

Galera Cluster กับ ProxySQL — จัดการ Read/Write Splitting

ProxySQL เป็นตัวเลือกที่ทรงพลังกว่า HAProxy สำหรับ MySQL/MariaDB โดยเฉพาะ รองรับ Read/Write Splitting โดยอัตโนมัติ — คำสั่ง SELECT ส่งไปโหนดที่ว่าง คำสั่ง INSERT/UPDATE/DELETE ส่งไปโหนดหลัก ช่วยกระจาย load ได้สมดุลกว่า HAProxy

ติดตั้ง ProxySQL บนเครื่อง Load Balancer:

sudo apt install -y proxysql
sudo systemctl start proxysql
sudo systemctl enable proxysql

เชื่อมต่อ ProxySQL Admin Interface:

mysql -u admin -padmin -h 127.0.0.1 -P6032

เพิ่ม backend servers ทั้ง 3 โหนด:

INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight) VALUES
(0, '10.0.0.11', 3306, 1),
(0, '10.0.0.12', 3306, 1),
(0, '10.0.0.13', 3306, 1);

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

ProxySQL vs HAProxy สำหรับ Galera: HAProxy ทำงานที่ TCP Layer 4 ไม่เข้าใจ SQL ส่วน ProxySQL ทำงานที่ Application Layer 7 เข้าใจ Query Type ได้ เหมาะกับระบบที่ต้องการ Read Scaling จริงจัง

วางแผน Capacity และการขยาย Cluster

Galera Cluster เหมาะกับ Write-heavy workload ขนาดกลาง แต่มีข้อจำกัดที่ต้องวางแผนล่วงหน้า:

จำนวนโหนด โหนดล่มได้สูงสุด เหมาะกับ
3 โหนด1 โหนดระบบ HA ทั่วไป, E-commerce, Web App
5 โหนด2 โหนดMission-critical, ต้องการ quorum แข็งแกร่ง
7 โหนด3 โหนดระดับ Enterprise, ต้องการ fault tolerance สูง

เมื่อวางแผน capacity ให้คำนึงถึงว่า RAM ต่อโหนดต้องรองรับ InnoDB Buffer Pool ซึ่งควรตั้งเป็น 70-80% ของ RAM ทั้งหมด เพื่อประสิทธิภาพสูงสุด:

# ใน /etc/mysql/mariadb.conf.d/50-server.cnf
innodb_buffer_pool_size = 1G  # สำหรับ VPS RAM 2GB
innodb_buffer_pool_instances = 2
innodb_log_file_size = 256M

Checklist หลังตั้ง Galera Cluster

  1. ใช้โหนด odd number เสมอ (3, 5, 7) — ห้ามใช้ 2 หรือ 4
  2. เปิด Firewall เฉพาะ port 3306, 4444, 4567, 4568 ระหว่างโหนดเท่านั้น
  3. Network latency ระหว่างโหนดควรต่ำ < 5ms — ไม่เหมาะกับ cross-region
  4. ใช้ HAProxy / ProxySQL หน้า Cluster — แอปอย่าต่อตรงไปโหนดเดียว
  5. Backup ปกติยังต้องทำ — Cluster ไม่ใช่ Backup (replication ของ DROP TABLE ก็ replicate ทันที!)
  6. Monitor wsrep_cluster_size และ wsrep_local_state_comment ผ่าน Netdata / Prometheus
  7. ตั้งค่า innodb_buffer_pool_size ให้เหมาะสมกับ RAM ของแต่ละโหนด
  8. ทดสอบ Failover จริงโดยหยุดโหนดหนึ่งแล้วตรวจว่า Cluster ยัง Active ปกติ
  9. ตั้ง Alert ผ่าน Prometheus หรือ Netdata เมื่อ wsrep_cluster_size ต่ำกว่า 3
  10. ทบทวน Galera version ทุก 6 เดือน และ upgrade MariaDB พร้อมกันทุกโหนดในช่วง maintenance window

สรุป — เมื่อไหรควรใช้ Galera Cluster

Galera Cluster เป็นทางเลือกที่ยอดเยี่ยมเมื่อระบบของคุณต้องการ High Availability ระดับ Database และไม่ยอมรับ downtime แม้แต่วินาทีเดียวเมื่อโหนดหนึ่งล่ม เหมาะกับ:

อย่างไรก็ตาม Galera ไม่เหมาะกับทุกสถานการณ์ — ถ้า workload ส่วนใหญ่เป็น Read-only การใช้ Master-Slave พร้อม Read Replica หลายตัวอาจตอบโจทย์ได้ดีกว่าในแง่ cost และความง่ายในการดูแล และถ้าต้องการ DB ข้ามหลาย Region แนะนำให้ศึกษา Galera Arbitrator (garbd) ซึ่งช่วย maintain quorum โดยไม่ต้องเปิดโหนด Database เต็มรูปแบบในทุก Region

AsiaGB VPS ในไทยและสิงคโปร์เหมาะสำหรับการตั้ง Galera Cluster เพราะอยู่ในศูนย์ข้อมูลเดียวกัน ทำให้ Network latency ระหว่างโหนดต่ำมาก ส่งผลดีต่อประสิทธิภาพของ Synchronous Replication โดยตรง คุณสามารถสั่ง VPS หลายเครื่องพร้อมกันได้ในทำเลที่ต้องการ พร้อม SSD เร็วและ Dedicated IP สำหรับแต่ละโหนด

ต้องการหลาย VPS สำหรับ Galera Cluster?

AsiaGB VPS เริ่มต้น 500 บาท/เดือน SSD เร็ว เปิดได้หลายเครื่องในทำเลเดียวกัน Network ต่ำ < 1ms ในศูนย์ข้อมูลเดียวกัน เหมาะกับ Cluster

ดูแพ็กเกจ VPS