Back to blog

Galera Cluster Architecture: Synchronous Multi-Master Replication

mysqlgalerareplicationdatabasehigh-availability
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:

PropertyAsync ReplicationGalera
Write nodes1 (primary)Tất cả node
Commit guaranteeChỉ localTất cả node trong quorum
Replication lagCó (ms đến hours)Không
FailoverExternal tool + downtimeTự động, không mất data
Conflict resolutionKhông cần (single writer)Certification-based
ProtocolBinlog streamingwsrep (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 local
  • wsrep_commit_cb — gọi để commit write-set đã apply từ remote
  • wsrep_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:

  1. Transaction execute bình thường trên local node (INSERT, UPDATE, DELETE)
  2. Tại thời điểm COMMIT, MySQL build write-set (tập row changes) và pass cho Galera library qua wsrep
  3. Galera broadcast write-set đến tất cả node dùng group communication
  4. Tất cả node certify write-set (check conflict)
  5. Nếu certification pass, transaction commit trên tất cả node
  6. 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-v2

Biế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–4GB
  • evs.suspect_timeout — Bao lâu trước khi node ngừng respond bị nghi ngờ đã chết
  • evs.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

Statewsrep_local_stateÝ nghĩa
Open1Node đã join group communication nhưng chưa nhận cluster state
Primary2Node đã nhận primary component view (biết ai đang trong cluster)
Joiner3Node đang nhận state transfer (SST hoặc IST) từ donor
Joined4State transfer xong, node đang catch up apply queue
Synced5Node đã fully synchronized — safe cho read và write
Donor6Node đ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: 3

Quan 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.0

Cờ đỏ: 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 ... SELECT di chuyển hàng triệu row block apply queue
  • DDL operation — ALTER TABLE dướ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 SizeChịu được lỗiMinimum cho Quorum
2 node0 (!)2
3 node12
4 node13
5 node23
6 node24
7 node34

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:

MethodTác động DonorTốc độKhuyến nghị
xtrabackup-v2Tối thiểu (non-blocking)Nhanh✅ Có
rsyncBlock readTrung bình❌ Không (cho production)
mysqldumpCPU/IO caoChậm❌ Không
clone (MySQL 8.0.17+)Tối thiểuNhanh✅ 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ại

Hiệ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 affected

Write 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ố node

Replication 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-order

Transaction 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:

  1. Không mất data khi failover — mọi write đã commit tồn tại trên tất cả surviving node
  2. Không replication lag — certification là synchronous; đọc từ bất kỳ node nào đều current
  3. Tự động conflict resolution — certification bắt conflict mà không cần distributed lock
  4. Tự phục hồi — node rejoin qua IST/SST tự động, không cần manual intervention
  5. 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.