Chapter 15 · Galera Cluster: Synchronous Multi-Primary Replication and High Availability

Galera Architecture, Write Sets, Certification, Quorum, and Cluster Membership

Understand MariaDB Galera as a wsrep-provider, write-set certification system with quorum and explicit node states, then build and verify a disposable three-node Community cluster without confusing cluster membership with client routing.

Advanced150–190 minutes3-node Galera architecture + quorum labMariaDB Community 12.3.2 + Galera 4 baselineCurriculum anchor: 11.8 LTS · verify server/provider/SST versionsLinux nodes/containers · Last reviewed: August 2026

Learning outcomes

ServiceHub has outgrown a single MariaDB server. The team wants a database topology that can survive one node failure without waiting for an asynchronous replica to catch up, and it wants more than one node capable of accepting writes. Calling that requirement “multi-master” is not enough. MariaDB Galera Cluster changes the commit path itself: transactions are converted into write sets, globally ordered by the Galera group-communication layer, checked by certification, and then applied on every cluster member.

Galera is the write-set replication provider integrated with MariaDB through the wsrep API (Write Set REPlication API). A Primary Component is the cluster membership group that has quorum and is allowed to process replicated updates. Quorum is a majority decision over the configured membership, not “the node with the newest timestamp.” Virtually synchronous means commit ordering/certification is coordinated across the active component, while remote row application can complete shortly after the originating node returns success.

01

Explain the MariaDB Server ↔ wsrep provider boundary and follow a transaction from local execution to write-set certification and remote apply.

02

Distinguish cluster membership, quorum, node readiness, and client routing as separate mechanisms.

03

Build a disposable three-node MariaDB Community 12.3.2 Galera cluster with Linux containers and verify the provider/version actually loaded.

04

Interpret wsrep status as evidence rather than treating “three mysqld processes are running” as cluster health.

05

Diagnose an unsafe one-node/incorrect-quorum assumption and choose a safe three-node operating model.

Platform and product boundary

MariaDB Galera Cluster is supported on Linux, not as a native Windows server build. A Windows or macOS workstation can still run this chapter with Linux containers or Linux virtual machines. Current MariaDB Community 12.3.2 packages/images include Galera components; always verify wsrep_provider_name and wsrep_provider_version on the exact image/package you deploy. Enterprise Cluster and MaxScale provide additional supported/managed capabilities, but no paid product is required for this chapter's mandatory labs.

1. Galera is inside the commit path, not a background binlog copier

Chapter 14's asynchronous replica receives binary-log events after the primary creates them. Galera is different. A transaction executed on node n1 accumulates changes locally. At commit, MariaDB exposes a write set containing the transaction's relevant keys/changes to the wsrep provider. The provider participates in global ordering and certification. If the transaction conflicts with a concurrently ordered write set, the local transaction can be rolled back even though its SQL statements executed successfully before COMMIT.

Mechanism Async replication Galera
write authority normally one primary multiple nodes can accept writes
transport unit binary-log events write sets through wsrep provider
conflict detection usually apply-time errors/drift certification before successful commit
membership safety external failover/control plane Primary Component + quorum protects replicated writes
client routing external still external

A cluster that is healthy at the wsrep layer does not automatically expose a single stable client endpoint. That separation becomes central in Lesson 4.

2. Certification is optimistic concurrency across nodes

Galera does not take a distributed lock before every update. Two transactions can execute independently on different nodes. When they reach replication, the ordered write sets are compared against the certification index. If both modify keys that cannot coexist in the same serial order, one transaction loses certification and the client sees a retryable transactional error.

This is why “all nodes accept writes” does not mean “writes scale linearly.” Workloads with independent rows can parallelize well; hot-row workloads can spend increasing time aborting/retrying. The application must treat commit failure as a normal distributed-database outcome.

Common wrong assumption

“If the UPDATE returned one affected row, the transaction is safe.” In Galera, a multi-statement transaction can still fail when COMMIT enters certification. Correct applications check commit errors and retry only when the business operation is idempotent or safely replayable.

3. Quorum creates one writable component

Membership changes create components. The component with quorum becomes Primary; a minority partition becomes Non-Primary and will normally reject replicated application work rather than independently accepting divergent writes. In an ordinary equally weighted three-node cluster, two mutually connected nodes retain quorum if the third is isolated.

Variable Healthy evidence What it does not prove
wsrep_cluster_status Primary all expected members are present
wsrep_cluster_size expected component size application is routing only to safe nodes
wsrep_connected ON node is synced/ready
wsrep_local_state_comment Synced no flow-control/performance problem
wsrep_ready ON your proxy is checking the right signal

4. Reproducible three-node Community lab

Save the following as compose.yaml. The official MariaDB 12.3.2 image currently installs the Galera-capable server package and exposes the provider at /usr/lib/galera/libgalera_smm.so. The lab uses rsync for State Snapshot Transfer (SST) because it avoids introducing SST database credentials before Lesson 2. It is intentionally a disposable local topology.

yaml · compose.yaml — three disposable Galera nodes
services:  n1:    image: mariadb:12.3.2    container_name: mdb15-n1    environment:      MARIADB_ROOT_PASSWORD: labroot    command:      - --bind-address=0.0.0.0      - --binlog-format=ROW      - --default-storage-engine=InnoDB      - --innodb-autoinc-lock-mode=2      - --wsrep-on=ON      - --wsrep-provider=/usr/lib/galera/libgalera_smm.so      - --wsrep-cluster-name=servicehub15      - --wsrep-cluster-address=gcomm://n2,n3      - --wsrep-node-name=n1      - --wsrep-sst-method=rsync      - --wsrep-new-cluster    ports:      - "33151:3306"  n2:    image: mariadb:12.3.2    container_name: mdb15-n2    environment:      MARIADB_ROOT_PASSWORD: labroot    command:      - --bind-address=0.0.0.0      - --binlog-format=ROW      - --default-storage-engine=InnoDB      - --innodb-autoinc-lock-mode=2      - --wsrep-on=ON      - --wsrep-provider=/usr/lib/galera/libgalera_smm.so      - --wsrep-cluster-name=servicehub15      - --wsrep-cluster-address=gcomm://n1      - --wsrep-node-name=n2      - --wsrep-sst-method=rsync    ports:      - "33152:3306"  n3:    image: mariadb:12.3.2    container_name: mdb15-n3    environment:      MARIADB_ROOT_PASSWORD: labroot    command:      - --bind-address=0.0.0.0      - --binlog-format=ROW      - --default-storage-engine=InnoDB      - --innodb-autoinc-lock-mode=2      - --wsrep-on=ON      - --wsrep-provider=/usr/lib/galera/libgalera_smm.so      - --wsrep-cluster-name=servicehub15      - --wsrep-cluster-address=gcomm://n1      - --wsrep-node-name=n3      - --wsrep-sst-method=rsync    ports:      - "33153:3306"
One-time bootstrap flag

The --wsrep-new-cluster option on n1 is valid only to create this brand-new lab cluster. MariaDB explicitly warns not to leave it in normal persistent startup configuration. After the cluster reaches three Synced nodes, remove that one line from n1 before using docker compose restart n1 or reusing the file for a persistent lab. Bootstrapping an existing member as a new cluster can create a second cluster UUID and a split-brain/data-divergence incident.

shell · start in bootstrap-then-join order
docker compose down -v --remove-orphans# Bootstrap exactly one node for a brand-new disposable cluster.docker compose up -d n1# Wait until n1 reports wsrep_ready=ON, then join the other nodes.docker compose up -d n2 n3# Verify all three nodes before creating application data.docker exec mdb15-n1 mariadb -uroot -plabroot -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size'; SHOW GLOBAL STATUS LIKE 'wsrep_cluster_status';"docker exec mdb15-n2 mariadb -uroot -plabroot -e "SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment';"docker exec mdb15-n3 mariadb -uroot -plabroot -e "SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment';"

Now connect to each node and run the same status query.

sql · run on n1, n2, and n3
SHOW GLOBAL STATUS WHERE Variable_name IN (  'wsrep_cluster_status','wsrep_cluster_size','wsrep_cluster_state_uuid',  'wsrep_connected','wsrep_ready','wsrep_local_state_comment',  'wsrep_provider_name','wsrep_provider_version','wsrep_last_committed');SHOW GLOBAL VARIABLES WHERE Variable_name IN (  'wsrep_on','wsrep_cluster_name','wsrep_cluster_address',  'wsrep_sst_method','binlog_format','innodb_autoinc_lock_mode');
Expected state

Each node should report provider Galera, the same cluster state UUID, wsrep_cluster_status=Primary, wsrep_cluster_size=3, wsrep_connected=ON, wsrep_ready=ON, and local state Synced. Provider version is an observation you record, not a value this lesson hard-codes.

5. Prove a write is replicated, then prove that routing is separate

sql · n1 — create the ServiceHub fixture
CREATE DATABASE IF NOT EXISTS servicehub_galera_lab;CREATE TABLE IF NOT EXISTS servicehub_galera_lab.tickets (  ticket_id BIGINT PRIMARY KEY AUTO_INCREMENT,  customer_id BIGINT NOT NULL,  state VARCHAR(24) NOT NULL,  priority INT NOT NULL DEFAULT 0,  updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)             ON UPDATE CURRENT_TIMESTAMP(6)) ENGINE=InnoDB;CREATE TABLE IF NOT EXISTS servicehub_galera_lab.counters (  counter_name VARCHAR(64) PRIMARY KEY,  counter_value BIGINT NOT NULL) ENGINE=InnoDB;INSERT INTO servicehub_galera_lab.counters(counter_name,counter_value)VALUES ('dispatch',0)ON DUPLICATE KEY UPDATE counter_value=VALUES(counter_value);INSERT INTO servicehub_galera_lab.tickets(customer_id,state,priority) VALUES (101,'open',2);
sql · n2 — read the row created on n1
SELECT ticket_id,customer_id,state,priorityFROM servicehub_galera_lab.ticketsORDER BY ticket_id;
sql · n3 — write from a second primary node
INSERT INTO servicehub_galera_lab.tickets(customer_id,state,priority)VALUES (202,'assigned',4);SELECT LAST_INSERT_ID();
sql · n1 — verify both writes are present
SELECT ticket_id,customer_id,state,priorityFROM servicehub_galera_lab.ticketsORDER BY ticket_id;

The replication evidence proves cluster data flow. It does not create an application endpoint. Your client still connected explicitly to n1/n2/n3. A proxy, service discovery layer, DNS policy, connection pool, or application retry/routing strategy must decide where new connections go.

6. Wrong approach: “two nodes are enough because data is duplicated”

A two-node cluster has two copies but awkward quorum behavior. If communication between the nodes is lost, neither side can safely assume the other is dead and independently continue as the only writer. Operators sometimes “fix” this by manually bootstrapping one side. That is dangerous because the other side may still be serving clients or may later return with divergent state.

For the lab, do not force a second bootstrap. Instead, stop n3 gracefully and observe the membership view on n1/n2, then start n3 and verify it returns to Synced. The lesson is that redundancy, quorum, and routing are different requirements.

shell · safe membership observation
docker stop mdb15-n3docker exec mdb15-n1 mariadb -uroot -plabroot -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_cluster_size','wsrep_cluster_status');"docker start mdb15-n3

After n3 catches up, verify all three nodes again. A temporary size of 2 is expected after a graceful leave; do not infer that a permanently designed two-node cluster has the same failure tolerance as three independent voting members.

7. What “virtually synchronous” does and does not promise

  • Successful commits are globally ordered/certified with the active Primary Component; this is much stronger than “ship the binlog later.”
  • Remote nodes can still have receive/apply queues; successful certification does not mean every remote storage page changed before the client received success.
  • A node that is not ready/synced must not be treated as a normal application target.
  • Network latency becomes part of write latency because commit requires cluster communication.
  • Galera is not a backup. Replicated mistakes and logical corruption can reach all nodes quickly.

8. Production judgment

Use Galera when you need a tightly coupled, quorum-based multi-primary cluster and your workload tolerates certification semantics and inter-node latency. Prefer an odd number of voting members placed so a majority can survive the failures you care about. Keep InnoDB tables keyed, use row binlogging, verify the exact server/provider combination, and design application retry behavior before enabling writes on several nodes.

Do not choose Galera merely because “three copies are safer.” Backups, disaster recovery, client routing, security, schema-change policy, capacity matching, and operational drills remain separate disciplines.

Check your understanding

  1. What is a write set and when is it certified?
  2. Why can COMMIT fail after all SQL statements appeared to execute normally?
  3. Which wsrep fields prove that a node is in a writable Primary Component and ready for queries?
  4. Why does a three-node Galera cluster still need a proxy or application routing policy?
  5. What is wrong with leaving --wsrep-new-cluster in normal startup configuration?
Review the answers

A write set is the transaction change/key payload exposed to Galera at replication/commit time; certification checks its ordered conflicts. A transaction can lose certification at commit, so execution success before COMMIT is not final success. Healthy routing gates normally include Primary component status, expected cluster size, connected/ready state, and a Synced local state. Galera manages database membership, not the client endpoint. The bootstrap flag creates a new cluster identity and can split an existing topology if reused incorrectly.

shell · cleanup when you are done
docker compose down -v --remove-orphans

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.