← กลับ
MariaDBGaleraDatabaseTroubleshooting

Debug MariaDB Galera Cluster หลุด (Node Disconnect)

node ใน Galera cluster หลุด split-brain ตอนกลับมาก็ join ไม่ได้ ตามวิธีกู้ทีละขั้น พร้อมหา root cause ของ network/restart พังบ่อย

2026-02-15อ่าน 7 นาทีใหม่

อาการที่เจอ

3-node Galera cluster อยู่ๆ มี node หลุด:

SHOW STATUS LIKE 'wsrep_cluster_size';
+---------------------+-------+
| wsrep_cluster_size  | 2     |   ← ปกติ 3
+---------------------+-------+

SHOW STATUS LIKE 'wsrep_local_state_comment';
+---------------------------+--------------+
| wsrep_local_state_comment | Disconnected |
+---------------------------+--------------+

หรือ:

[Warning] WSREP: Quorum: No node with complete state:
[ERROR] WSREP: Cluster member missing

ในกรณีร้ายแรง — ทั้ง 3 node "Disconnected" จาก quorum (split-brain) ทุกตัวอ่าน-เขียนไม่ได้

ก่อนแก้ — เข้าใจ Galera ก่อน

Galera = synchronous multi-master replication

  • ทุก node เขียนได้พร้อมกัน
  • ต้องมี quorum (เกินครึ่งของ cluster size) ถึงจะรับ write
  • Cluster 3 node — ต้องมี 2 node alive ขึ้นไปถึงจะทำงาน

ถ้า node ส่วนใหญ่หายไป — ที่เหลือเข้า "non-Primary" state รับ write ไม่ได้ — กันไม่ให้ split-brain

ขั้นตอน Debug

Step 1: ดูสถานะแต่ละ node

ใน node ทุกตัวรัน:

SHOW STATUS LIKE 'wsrep_%';

ดู value เหล่านี้:

| Variable | ความหมาย | |---|---| | wsrep_cluster_size | จำนวน node ใน cluster ตอนนี้ | | wsrep_cluster_status | Primary = ดี, non-Primary = ปัญหา | | wsrep_connected | ON = connect ใน cluster อยู่ | | wsrep_ready | ON = รับ query ได้ | | wsrep_local_state_comment | Synced = ดี, อื่นๆ = ดู status |

Step 2: ดู error log

sudo tail -100 /var/log/mysql/error.log

หรือใน Docker:

docker logs --tail 200 mariadb

มอง keyword:

  • WSREP — เกี่ยวกับ Galera
  • Connection refused — node ติดต่อกันไม่ได้
  • gcomm — group communication
  • SST / IST — state transfer

Step 3: ตรวจ network ระหว่าง node

Galera ใช้ port:

  • 3306 — MySQL client
  • 4567 — Galera replication (TCP + UDP)
  • 4568 — IST (incremental state transfer)
  • 4444 — SST (snapshot state transfer)

ตรวจจาก node A → node B:

nc -zv node-b 3306
nc -zv node-b 4567
nc -zv node-b 4568
nc -zv node-b 4444

ถ้า port ไหนเชื่อมไม่ได้ — firewall block

# Ubuntu ufw
sudo ufw allow from 10.0.0.0/24 to any port 3306,4444,4567,4568 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 4567 proto udp

วิธีกู้คืน

Case A: 1 node หลุดจาก 3

ปกติ node ที่หลุดจะกลับเข้ามาเอง — ตรวจ status:

sudo systemctl status mariadb

ถ้า service ยังรัน restart:

sudo systemctl restart mariadb

ดู log ว่า rejoin ได้มั้ย:

sudo tail -f /var/log/mysql/error.log

ควรเห็น:

[Note] WSREP: Member ... synced with group
[Note] WSREP: ... SYNCED -> JOINED

Case B: ทุก node Disconnected (split-brain)

ทุก node "non-Primary" — ใครจะ start cluster ก่อน?

ขั้นที่ 1: หา node ที่ commit transaction ล่าสุด

ใน node แต่ละตัวรัน:

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

ดู:

seqno: 1842903

node ที่ seqno สูงสุด = มี data ใหม่ที่สุด = ควร bootstrap cluster

ถ้า seqno = -1:

sudo mysqld_safe --wsrep-recover
# จะเห็น "Recovered position: <uuid>:<seqno>"

ขั้นที่ 2: bootstrap จาก node นั้น

หยุด mariadb ทุก node ก่อน:

sudo systemctl stop mariadb

บน node ที่ seqno สูงสุด — set safe_to_bootstrap = 1:

sudo nano /var/lib/mysql/grastate.dat
safe_to_bootstrap: 1

bootstrap:

sudo galera_new_cluster
# หรือ
sudo systemctl start mariadb@bootstrap

ตรวจสอบ:

SHOW STATUS LIKE 'wsrep_cluster_status';
-- Primary

ขั้นที่ 3: start node อื่นกลับเข้า cluster

# บน node 2 และ 3
sudo systemctl start mariadb

node อื่นจะ SST/IST จาก node แรก แล้ว sync

SHOW STATUS LIKE 'wsrep_cluster_size';
-- 3

Case C: SST stuck

ถ้า node ใหม่ join แล้วค้างที่ "Joiner" นาน — SST อาจช้า/ค้าง

ตรวจ:

ps aux | grep -E "rsync|xtrabackup|mariabackup"

ถ้าไม่มี process — restart node:

sudo systemctl restart mariadb

ลด SST timeout / เปลี่ยน method ใน config:

/etc/mysql/mariadb.conf.d/galera.cnf:

wsrep_sst_method=mariabackup     # เร็วกว่า rsync
wsrep_sst_auth=sstuser:password

ป้องกันการหลุดในอนาคต

1. ใช้ network เสถียร — ไม่ใช่ public internet

Galera ไวกับ latency มาก — > 100ms = อาจ flaky

ใช้:

  • VPC/private network ของ cloud provider
  • VPN เช่น Tailscale / WireGuard
  • Direct connect ระหว่าง data center

2. Tune timeout ให้รับ latency

galera.cnf:

# default 5s — เพิ่มถ้า latency สูง
wsrep_provider_options="evs.suspect_timeout=PT15S;evs.inactive_timeout=PT45S;evs.keepalive_period=PT3S"

3. เปิด arbitrator ถ้ามี 2 node

Cluster 2 node = ถ้า node ตาย → quorum หาย ทั้ง cluster อ่านไม่ได้

ใช้ Galera Arbitrator (garbd) — node "พิเศษ" ที่ไม่เก็บ data แต่ vote ด้วย

sudo apt install galera-arbitrator-3

config /etc/default/garb:

GALERA_NODES="10.0.0.1:4567,10.0.0.2:4567"
GALERA_GROUP="my_cluster"

เปิดเป็น service:

sudo systemctl enable --now garb

4. Monitor + Alert

ตั้ง alert ใน Prometheus / Uptime Kuma:

mysql_global_status_wsrep_cluster_size < 3
mysql_global_status_wsrep_local_state{state!="Synced"}

หรือเขียน script เช็ค:

#!/bin/bash
SIZE=$(mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';" | awk 'NR==2 {print $2}')
if [ "$SIZE" != "3" ]; then
  curl -X POST $SLACK_WEBHOOK -d '{"text":"⚠️ Galera cluster size: '"$SIZE"'"}'
fi

cron ทุก 5 นาที

5. Backup ข้อมูลด้วย mariabackup

อย่าพึ่ง replication อย่างเดียว — Galera replicate bug/delete กระจายทันที

ตั้ง backup รายวัน:

mariabackup --backup --target-dir=/data/backup/$(date +%F) \
  --user=backup --password=...

ดูเพิ่ม: Backup Database อัตโนมัติ

เครื่องมือช่วย debug

# Node status สรุปย่อ
mysql -e "SHOW STATUS LIKE 'wsrep_%';" | grep -E "cluster_size|cluster_status|connected|local_state_comment|ready"

# ดู GTID history
mysql -e "SELECT @@gtid_current_pos;"

# ดู replication lag (ถ้ามี async slave ด้วย)
mysql -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master

เช็คลิสต์เวลาเจอ

  1. ✅ ดู wsrep_cluster_size, wsrep_cluster_status ใน node ทุกตัว
  2. ✅ ดู error log
  3. ✅ เช็ค network connectivity port 4567/4568/4444
  4. ✅ เช็ค seqno ใน grastate.dat
  5. ✅ ถ้าทุก node down → bootstrap จาก node ที่ seqno สูงสุด
  6. ✅ ตั้ง alert ป้องกันครั้งหน้า

สรุป

Galera หลุด เกือบทั้งหมดมาจาก network ระหว่าง node — ตรวจ network ก่อนเสมอ

ถ้าพังจริง ๆ — grastate.dat คือกุญแจ ดู seqno เพื่อรู้ว่า node ไหนจะ bootstrap

ป้องกันด้วย: network ที่ดี + arbitrator (ถ้า 2 node) + monitor + backup

← ดูบทความอื่น