Galera Cluster Architecture: Synchronous Multi-Master Replication

Post 2 cho bạn thấy MySQL replication làm được gì và chỗ nào nó vỡ. Async replication có durability gap. Semi-sync đóng gap một phần nhưng có thể âm thầm fall back. Failover cần external tool và ~30 giây downtime. Và không cái nào cho bạn multi-master writes.
Galera đi một hướng khác hoàn toàn. Thay vì stream binary log event từ node này sang node kia, Galera đóng gói mỗi transaction thành một write-set, broadcast nó đến tất cả node, và dùng thuật toán certification để quyết định — atomically, trên mọi node — liệu transaction đó có được commit hay không.
Bài này giải thích cách nó hoạt động, từ protocol layer đến operational behavior.
Galera Khác Gì So Với Replication Thường?
MySQL replication truyền thống là asynchronous và single-primary: một node nhận write, các node khác replay lại sau. Galera là virtually synchronous và multi-master: mọi node đều nhận write được, và mọi transaction đã commit đảm bảo tồn tại trên tất cả node.
So sánh nhanh:
| Property | Async Replication | Galera |
|---|---|---|
| Write nodes | 1 (primary) | Tất cả node |
| Commit guarantee | Chỉ local | Tất cả node trong quorum |
| Replication lag | Có (ms đến hours) | Không |
| Failover | External tool + downtime | Tự động, không mất data |
| Conflict resolution | Không cần (single writer) | Certification-based |
| Protocol | Binlog streaming | wsrep (Write-Set Replication) |
Thuật ngữ "virtually synchronous" quan trọng: Galera không dùng distributed two-phase commit (2PC). Thay vào đó, nó dùng group communication protocol — tất cả node đồng thuận về thứ tự transaction, rồi mỗi node tự independently apply transaction. Commit là synchronous từ góc nhìn application — khi COMMIT trả về OK, mọi node đã có write-set — nhưng bước apply thực tế trên remote node xảy ra asynchronously.
wsrep API
Galera không modify MySQL server. Thay vào đó, nó dùng replication plugin API gọi là wsrep (Write-Set Replication). Đây là interface giữa MySQL (hoặc MariaDB, hoặc Percona Server) và Galera replication library.
wsrep API định nghĩa một tập callback:
wsrep_apply_cb— gọi khi remote write-set đến và cần apply localwsrep_commit_cb— gọi để commit write-set đã apply từ remotewsrep_unordered_cb— cho unordered event (ít dùng)wsrep_sst_donate_cb— gọi trên donor node trong State Snapshot Transfer
Từ phía MySQL, wsrep API hook vào commit path:
- Transaction execute bình thường trên local node (INSERT, UPDATE, DELETE)
- Tại thời điểm
COMMIT, MySQL build write-set (tập row changes) và pass cho Galera library qua wsrep - Galera broadcast write-set đến tất cả node dùng group communication
- Tất cả node certify write-set (check conflict)
- Nếu certification pass, transaction commit trên tất cả node
- Nếu certification fail, node gốc rollback và trả error
Điểm mấu chốt: Galera không replicate SQL statement. Nó replicate hiệu ứng của statement — actual row-level changes. Tương tự row-based binary logging, nhưng format và protocol hoàn toàn khác.
wsrep Provider Options
Galera library được load qua biến config wsrep_provider:
[mysqld]
wsrep_provider=/usr/lib64/galera4/libgalera_smm.so
wsrep_cluster_address=gcomm://node1,node2,node3
wsrep_cluster_name=my_cluster
wsrep_node_name=node1
wsrep_node_address=192.168.1.10
wsrep_sst_method=xtrabackup-v2Biến wsrep_provider_options điều khiển behavior internal của Galera library:
wsrep_provider_options="gcache.size=1G; evs.keepalive_period=PT3S; evs.suspect_timeout=PT30S; evs.inactive_timeout=PT1M"Mình sẽ cover tunning chi tiết ở Post 8 (Performance Tuning), nhưng những cái quan trọng cần biết ngay:
gcache.size— Kích thước Galera write-set cache (dùng cho IST). Default 128MB, production cluster thường dùng 1–4GBevs.suspect_timeout— Bao lâu trước khi node ngừng respond bị nghi ngờ đã chếtevs.inactive_timeout— Bao lâu trước khi node bị nghi ngờ bị đuổi khỏi cluster
Write-Set Replication: Transaction Đi Như Thế Nào?
Đây là trái tim của Galera. Hãy trace một write từ application đến commit trên tất cả node.
Bước 1: Local Execution
Application connect đến bất kỳ Galera node nào và execute transaction:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 42;
UPDATE accounts SET balance = balance + 100 WHERE id = 99;
COMMIT;Trong block BEGIN ... COMMIT, transaction execute locally trên node đang kết nối — y như MySQL transaction bình thường. InnoDB acquire row lock, modify page trong buffer pool, ghi redo log. Tại thời điểm này, không node nào khác biết về transaction này.
Bước 2: Write-Set Construction
Tại thời điểm COMMIT, wsrep hook chặn commit lại. MySQL build write-set chứa:
- Row changes (before và after image cho mỗi row bị modify)
- Key set — primary key của tất cả row bị touch (dùng cho certification)
- Database và table name
- GTID của transaction (Galera dùng format GTID riêng, tách biệt khỏi MySQL GTID)
Write-set là compact binary representation — không chứa SQL text, chỉ row-level diff.
Bước 3: Broadcast (Total Order)
Galera gửi write-set đến tất cả node qua group communication system (GCS). GCS đảm bảo total order delivery: mọi node nhận write-set theo đúng thứ tự, dù nhiều node gửi write-set cùng lúc.
Sequence number (seqno) cực kỳ quan trọng. Nó đảm bảo tất cả node xử lý write-set theo cùng thứ tự. Đây là thứ khiến certification trở nên deterministic — mọi node thấy cùng history và đi đến cùng quyết định certification một cách independent.
Bước 4: Certification
Khi node nhận write-set (kể cả node gốc), nó chạy certification test. Đây là thuật toán conflict detection kiểm tra:
"Key set của write-set này có overlap với write-set nào đã được certify SAU khi transaction này bắt đầu nhưng TRƯỚC sequence number của transaction này không?"
Nói đơn giản hơn: có transaction nào khác modify cùng row giữa lúc transaction này bắt đầu đọc và lúc nó cố commit không?
Certification index là in-memory data structure map primary key đến sequence number của write-set cuối cùng modify chúng. Nhẹ và nhanh.
Nếu certification pass: Write-set được thêm vào apply queue. Trên node gốc, transaction commit ngay. Trên remote node, background applier thread replay write-set.
Nếu certification fail: Node gốc nhận DEADLOCK error (error code 1213) và phải retry transaction. Remote node đơn giản discard write-set.
Tại Sao Certification Hoạt Động?
Certification là deterministic: mọi node có cùng certification index (vì chúng xử lý write-set theo cùng thứ tự), nên mọi node đi đến cùng quyết định PASS/FAIL một cách independent. Không cần voting round.
Đây khác biệt cơ bản so với two-phase commit (2PC) truyền thống:
- 2PC: Coordinator hỏi "bạn commit được không?" → node vote → coordinator quyết định → node commit/abort
- Galera certification: Mỗi node tự xác định write-set có commit được không, và luôn đồng ý vì thấy cùng sequence of event
Điều này khiến Galera nhanh hơn 2PC trong operation bình thường — chỉ một network round-trip (broadcast), không phải hai (prepare + commit).
Certification Conflict: Khi Write Va Chạm
Trong multi-master cluster, hai node có thể nhận write modify cùng row cùng lúc. Galera xử lý qua certification — nhưng application của bạn phải sẵn sàng cho certification failure.
Ví Dụ: Hai Update Đồng Thời
Transaction của Node 2 hợp lệ locally, nhưng globally nó conflict với transaction của Node 1 có sequence number thấp hơn. Node 2 trả deadlock error cho application.
Xử Lý Certification Failure Trong Application
Application bắt buộc phải handle error 1213 với retry logic:
import mysql.connector
import time
def execute_with_retry(connection, query, params=None, max_retries=3):
for attempt in range(max_retries):
try:
cursor = connection.cursor()
cursor.execute("BEGIN")
cursor.execute(query, params)
connection.commit()
return cursor
except mysql.connector.Error as e:
if e.errno == 1213 and attempt < max_retries - 1:
# Certification failure — retry với backoff
time.sleep(0.1 * (2 ** attempt))
continue
raiseĐiểm mấu chốt: Certification failure là expected trong multi-master mode. Chúng không phải bug — chúng là cơ chế bảo toàn consistency. Nếu bạn không bao giờ gặp certification failure, hoặc bạn đang write vào một node duy nhất (ProxySQL route đúng rồi), hoặc workload không có write contention.
Giảm Thiểu Certification Conflict
Trong thực tế, hầu hết production Galera deployment route tất cả write vào một node duy nhất qua ProxySQL. Điều này loại bỏ certification conflict hoàn toàn trong khi giữ multi-master capability làm failover feature.
Nếu bạn write vào nhiều node:
- Tránh hot row: Một row được update từ nhiều node sẽ conflict thường xuyên
- Giữ transaction nhỏ: Ít row bị touch = ít key trong write-set = xác suất conflict thấp hơn
- Tránh long transaction: Transaction chạy 5 giây có window conflict lớn hơn nhiều so với 5ms
- Dùng optimistic locking trong application: Pattern check-and-set giảm blast radius của conflict
Galera Node States
Mỗi node trong Galera cluster chuyển qua một chuỗi state. Hiểu các state này là thiết yếu cho operation — chúng cho bạn biết node đang healthy, đang join, hay đang có vấn đề.
Chi Tiết Các State
| State | wsrep_local_state | Ý nghĩa |
|---|---|---|
| Open | 1 | Node đã join group communication nhưng chưa nhận cluster state |
| Primary | 2 | Node đã nhận primary component view (biết ai đang trong cluster) |
| Joiner | 3 | Node đang nhận state transfer (SST hoặc IST) từ donor |
| Joined | 4 | State transfer xong, node đang catch up apply queue |
| Synced | 5 | Node đã fully synchronized — safe cho read và write |
| Donor | 6 | Node đang gửi state cho joining node |
Monitor Node State
-- State hiện tại của node
SHOW STATUS LIKE 'wsrep_local_state_comment';
-- Output: Synced
-- Node sẵn sàng nhận query chưa?
SHOW STATUS LIKE 'wsrep_ready';
-- Output: ON
-- Node có trong primary component không?
SHOW STATUS LIKE 'wsrep_cluster_status';
-- Output: Primary
-- Bao nhiêu node trong cluster?
SHOW STATUS LIKE 'wsrep_cluster_size';
-- Output: 3Quan trọng: Node với wsrep_ready = OFF không nên nhận traffic. ProxySQL check điều này tự động qua health check (cover ở Post 5).
Vấn Đề Donor State
Khi node mới join và cần SST (full state transfer), donor node vào Donor state. Tùy SST method:
- xtrabackup-v2: Donor vẫn available cho read và write trong SST. Đây là method khuyến nghị.
- rsync: Donor bị block read trong quá trình transfer. Tránh dùng production.
- mysqldump: Donor available nhưng chịu tải nặng. Chậm cho dataset lớn.
Đây là lý do Percona XtraDB Cluster default dùng xtrabackup-v2 — đó là SST method duy nhất giữ donor fully operational.
Flow Control: Cơ Chế Throttle Toàn Cluster
Trong bất kỳ replication system nào, node có thể bị tụt lại. Trong async replication, bạn thấy đây là replication lag. Trong Galera, cluster không cho phép lag — thay vào đó, nó dùng flow control để làm chậm toàn bộ cluster khi một node không theo kịp.
Flow Control Hoạt Động Thế Nào?
Mỗi node có apply queue (còn gọi là receive queue) — write-set đã certify nhưng chưa apply vào local database. Nếu queue này phình quá lớn, node gửi flow control PAUSE message cho group. Tất cả node tạm pause certification cho đến khi slow node catch up.
Cấu Hình Flow Control
# Số write-set trong receive queue trước khi gửi FC_PAUSE
# Default: 16
wsrep_provider_options="gcs.fc_limit=64"
# Queue length mà FC_RESUME được gửi (fraction of fc_limit)
# Default: 0.5 (resume khi queue giảm xuống 50% fc_limit)
wsrep_provider_options="gcs.fc_master_slave=NO; gcs.fc_factor=0.5"Monitor Flow Control
-- Tỷ lệ thời gian cluster bị pause do flow control (0.0 = không bao giờ, 1.0 = luôn luôn)
SHOW STATUS LIKE 'wsrep_flow_control_paused';
-- Target: < 0.01 (dưới 1% paused)
-- Số flow control PAUSE event gửi bởi node này
SHOW STATUS LIKE 'wsrep_flow_control_sent';
-- Độ dài receive queue hiện tại
SHOW STATUS LIKE 'wsrep_local_recv_queue_avg';
-- Target: < 1.0Cờ đỏ: Nếu wsrep_flow_control_paused liên tục trên 0.1 (10%), write throughput của cluster đang bị throttle. Nguyên nhân thường gặp:
- Disk chậm trên một node — SSD vs spinning disk
- Hardware không đồng đều — một node ít RAM hoặc CPU chậm hơn
- Transaction lớn — một
INSERT ... SELECTdi chuyển hàng triệu row block apply queue - DDL operation —
ALTER TABLEdưới TOI mode block tất cả node
Quorum và Split-Brain Protection
Distributed system phải xử lý network partition — chuyện gì xảy ra khi node không communicate được với nhau? Galera dùng approach quorum-based để ngăn split-brain (hai nửa cluster nhận conflicting write độc lập).
Quy Tắc Quorum
Một partition phải chứa hơn một nửa membership cuối cùng của cluster để tiếp tục hoạt động. Đây gọi là Primary Component.
Với 3-node cluster:
- 2 node online: Quorum (2 > 3/2). Cluster hoạt động bình thường.
- 1 node online: Không quorum (1 ≤ 3/2). Node từ chối write.
- 3 node online: Quorum. Hoạt động bình thường.
Tại Sao Số Lẻ Quan Trọng?
Với số chẵn node, split 50/50 hoàn hảo nghĩa là không bên nào có quorum:
| Cluster Size | Chịu được lỗi | Minimum cho Quorum |
|---|---|---|
| 2 node | 0 (!) | 2 |
| 3 node | 1 | 2 |
| 4 node | 1 | 3 |
| 5 node | 2 | 3 |
| 6 node | 2 | 4 |
| 7 node | 3 | 4 |
Cluster 2 node nguy hiểm: nếu một node chết, node còn lại không có quorum và ngừng nhận write. Bạn cần ít nhất 3 node. Và chú ý 4 node chịu được cùng số failure như 3 — nên 3 là sweet spot cho hầu hết cluster.
Nếu bạn cần setup 2 node (ví dụ hai data center), có thể dùng Galera Arbitrator (garbd) — lightweight daemon tham gia quorum voting nhưng không lưu data. Nó đóng vai trò tiebreaker.
Monitor Quorum
-- Cluster status hiện tại
SHOW STATUS LIKE 'wsrep_cluster_status';
-- "Primary" = đang có quorum
-- "Non-primary" = mất quorum, từ chối write
-- Cluster size (số node trong view hiện tại)
SHOW STATUS LIKE 'wsrep_cluster_size';
-- ID của node này trong cluster
SHOW STATUS LIKE 'wsrep_local_index';Recovery Từ Non-Primary State
Nếu tất cả node mất quorum (ví dụ 3-node cluster reboot đồng thời), bạn cần bootstrap một node:
# Tìm node có data mới nhất
# Check grastate.dat trên mỗi node:
cat /var/lib/mysql/grastate.dat
# Tìm seqno cao nhất:
# ...
# seqno: 12345
# safe_to_bootstrap: 1
# ...
# Bootstrap từ node có data mới nhất:
# Trên node được chọn:
mysqld --wsrep-new-cluster
# Rồi start các node khác bình thường:
systemctl start mysqlĐừng bao giờ bootstrap node không có data mới nhất — bạn sẽ mất committed transaction.
SST vs IST: Node (Tái) Gia Nhập Cluster Như Thế Nào?
Khi node gia nhập cluster — lần đầu hoặc sau crash — nó cần dataset hiện tại. Galera có hai cơ chế:
SST (State Snapshot Transfer)
Full copy toàn bộ dataset từ donor node sang joining node. Dùng khi:
- Node join lần đầu
- Node down quá lâu, gcache của donor không đủ cover gap
- IST không khả dụng vì bất kỳ lý do nào
Các SST method:
| Method | Tác động Donor | Tốc độ | Khuyến nghị |
|---|---|---|---|
| xtrabackup-v2 | Tối thiểu (non-blocking) | Nhanh | ✅ Có |
| rsync | Block read | Trung bình | ❌ Không (cho production) |
| mysqldump | CPU/IO cao | Chậm | ❌ Không |
| clone (MySQL 8.0.17+) | Tối thiểu | Nhanh | ✅ Thay thế |
SST có thể mất rất lâu cho dataset lớn. Database 500GB qua mạng 1Gbps mất ~70 phút tốt nhất. Trong thời gian này, joiner không serve traffic và donor (nếu dùng rsync) bị degrade một phần.
IST (Incremental State Transfer)
Transfer một phần — chỉ các write-set mà node bỏ lỡ khi down. Nhanh hơn SST rất nhiều. Dùng khi:
- Node down ngắn
- Write-set bị thiếu vẫn còn trong gcache (Galera cache) của donor
IST nhanh hơn SST hàng bậc — catch up 500 write-set mất vài giây, không phải phút hay giờ.
gcache: Chìa Khóa Cho Rejoin Nhanh
gcache (Galera Cache) là ring buffer trên mỗi node lưu write-set gần đây. Khi node quay lại và request state transfer, donor check: "Mình có tất cả write-set mà node này bỏ lỡ trong gcache không?"
Nếu có → IST (nhanh). Nếu không → SST (chậm).
# Size gcache dựa trên write volume
# Rule of thumb: đủ chứa write-set cho thời gian downtime dài nhất expected
wsrep_provider_options="gcache.size=2G"Cách size gcache: Nếu cluster tạo 100MB write-set mỗi giờ và bạn muốn node down 4 giờ rejoin qua IST, set gcache.size=400M (cộng safety margin). Thực tế, 1–4GB đủ cho hầu hết workload.
Bạn có thể monitor gcache usage:
SHOW STATUS LIKE 'wsrep_local_cached_downto';
-- Seqno thấp nhất còn trong gcache
SHOW STATUS LIKE 'wsrep_last_committed';
-- Seqno cao nhất hiện tạiHiệu số cho biết bao nhiêu write-set được cache. Nếu node rejoin cần write-set dưới wsrep_local_cached_downto, IST không thể và SST kick in.
Galera Limitation
Galera mạnh, nhưng không phải giải pháp vạn năng. Hiểu limitation giúp bạn tránh sai lầm architecture.
Chỉ InnoDB
Galera replicate ở InnoDB level. MyISAM, MEMORY, và storage engine khác không được replicate. Write vào non-InnoDB table chỉ local — invisible với node khác.
Percona XtraDB Cluster Strict Mode (pxc_strict_mode=ENFORCING) reject tạo non-InnoDB table hoàn toàn.
Tất Cả Table Cần Primary Key
Galera certification dùng primary key để detect conflict. Table không có primary key:
- Không thể certify hiệu quả
- Gây full-table scan khi apply trên remote node
- Bị reject bởi PXC Strict Mode
Luôn định nghĩa primary key cho mọi table.
Không Large Transaction
Galera write-set được giữ trong memory khi certification và broadcast. Transaction modify hàng triệu row tạo write-set khổng lồ:
- Tiêu thụ memory trên tất cả node
- Mất thời gian broadcast
- Trigger flow control khi node khác xử lý
- Có thể vi phạm
wsrep_max_ws_size(default: 2GB)
Chia bulk operation thành batch. Thay vì:
-- Xấu: một transaction khổng lồ
DELETE FROM logs WHERE created_at < '2025-01-01';Dùng:
-- Tốt: chunked delete
DELETE FROM logs WHERE created_at < '2025-01-01' LIMIT 10000;
-- Lặp lại cho đến khi 0 row affectedWrite Scalability
Galera không scale write theo chiều ngang. Mọi write phải được certify và apply trên mọi node. Thêm node thực ra thêm certification overhead. Galera scale read (bất kỳ node nào serve SELECT query) nhưng không scale write.
Nếu bạn cần write scalability vượt quá khả năng một node, hãy xem application-level sharding hoặc Vitess (cover ở Post 10).
WAN Latency
Mỗi COMMIT trong Galera cần network round-trip đến tất cả node. Trên LAN (< 1ms latency), overhead không đáng kể. Qua WAN (50ms+ latency), mỗi commit mất ít nhất 50ms bất kể transaction đơn giản thế nào.
Galera hỗ trợ WAN segment (config qua gmcast.segment) để optimize communication topology, nhưng chi phí latency cơ bản vẫn còn.
Các wsrep Status Variable Thiết Yếu
Đây là monitoring cheat sheet — các biến bạn nên watch trong production:
Cluster Health
-- Cluster có hoạt động không?
SHOW STATUS LIKE 'wsrep_cluster_status'; -- Primary = tốt
SHOW STATUS LIKE 'wsrep_ready'; -- ON = nhận query
SHOW STATUS LIKE 'wsrep_connected'; -- ON = kết nối cluster
SHOW STATUS LIKE 'wsrep_cluster_size'; -- Số nodeReplication Performance
-- Flow control (nên gần 0)
SHOW STATUS LIKE 'wsrep_flow_control_paused'; -- Tỷ lệ thời gian bị pause
SHOW STATUS LIKE 'wsrep_flow_control_sent'; -- FC event gửi bởi node này
-- Độ dài queue (nên gần 0)
SHOW STATUS LIKE 'wsrep_local_recv_queue_avg'; -- Avg receive queue
SHOW STATUS LIKE 'wsrep_local_send_queue_avg'; -- Avg send queue
-- Certification
SHOW STATUS LIKE 'wsrep_cert_deps_distance'; -- Bao nhiêu write-set có thể apply song song
SHOW STATUS LIKE 'wsrep_apply_oooe'; -- Hiệu suất apply out-of-orderTransaction Statistics
-- Write-set statistics
SHOW STATUS LIKE 'wsrep_last_committed'; -- Seqno commit cao nhất
SHOW STATUS LIKE 'wsrep_replicated'; -- Write-set gửi bởi node này
SHOW STATUS LIKE 'wsrep_replicated_bytes'; -- Byte gửi
SHOW STATUS LIKE 'wsrep_received'; -- Write-set nhận từ node khác
SHOW STATUS LIKE 'wsrep_local_cert_failures'; -- Certification failure (conflict)
SHOW STATUS LIKE 'wsrep_local_bf_aborts'; -- Brute-force abort (conflict với remote apply)Ghép Tất Cả Lại
Đây là bức tranh hoàn chỉnh cách 3-node Galera cluster xử lý một write:
Các đảm bảo:
- Không mất data khi failover — mọi write đã commit tồn tại trên tất cả surviving node
- Không replication lag — certification là synchronous; đọc từ bất kỳ node nào đều current
- Tự động conflict resolution — certification bắt conflict mà không cần distributed lock
- Tự phục hồi — node rejoin qua IST/SST tự động, không cần manual intervention
- Không split-brain — quorum ngăn divergence trong network partition
Tiếp Theo
Giờ bạn đã hiểu theory đằng sau Galera. Bài tiếp theo, chúng ta biến theory thành practice với Percona XtraDB Cluster (PXC) — distribution production-ready của Galera. Bạn sẽ bootstrap 3-node cluster với Docker Compose, configure SST với XtraBackup, test node failure và recovery, và thấy PXC Strict Mode hoạt động.
Tiếp tục Post 4 → Percona XtraDB Cluster Setup
Series navigation:
← Post 2: MySQL Replication Fundamentals
→ Post 4: Percona XtraDB Cluster Setup
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.