Introduction
Galera Cluster is a MariaDB/MySQL extension for synchronous multi-master replication:
- All writes propagated synchronously to other nodes
- Write to any node
- Automatic failover (every node is "primary")
- Strong consistency (no eventual reads)
- Minimum 3 nodes recommended (avoid split-brain)
Limits:
- All tables must be InnoDB (no MyISAM, no TokuDB)
- LARGE transactions can be rejected (size / lock contention)
- Write latency = network latency between nodes
Use cases: write-heavy LAMP apps (high-traffic WordPress, e-commerce, SaaS).
Prerequisites
- 3 Linux VPS Debian / Ubuntu
- Private network between VPS
- IPs:
10.0.0.1,10.0.0.2,10.0.0.3 - Root access on each
Step 1: Install MariaDB on all 3 nodes
sudo apt update
sudo apt install -y mariadb-server mariadb-client galera-4
mariadb --version
Step 2: Firewall
Galera ports:
- 3306: MariaDB SQL
- 4567: Galera replication (TCP + UDP)
- 4568: IST (Incremental State Transfer)
- 4444: SST (State Snapshot Transfer)
On each node:
sudo ufw allow from 10.0.0.0/24 to any port 3306
sudo ufw allow from 10.0.0.0/24 to any port 4567 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 4567 proto udp
sudo ufw allow from 10.0.0.0/24 to any port 4568
sudo ufw allow from 10.0.0.0/24 to any port 4444
Step 3: Stop MariaDB everywhere
sudo systemctl stop mariadb
Step 4: Configure Galera
On each node, create /etc/mysql/mariadb.conf.d/60-galera.cnf:
[mysqld]
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_size=2G
bind-address=0.0.0.0
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="my_cluster"
wsrep_cluster_address="gcomm://10.0.0.1,10.0.0.2,10.0.0.3"
wsrep_sst_method=mariabackup
wsrep_sst_auth=sstuser:strong-sst-pass
# Node-specific: replace with node IP
wsrep_node_address="10.0.0.1"
wsrep_node_name="node1"
⚠️ On node2: wsrep_node_address="10.0.0.2", wsrep_node_name="node2". Same for node3.
Step 5: Create SST user
On node1 only, start in normal mode first:
sudo systemctl start mariadb
sudo mariadb
CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 'strong-sst-pass';
GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'sstuser'@'localhost';
FLUSH PRIVILEGES;
sudo systemctl stop mariadb
Step 6: Bootstrap the cluster
On node1:
sudo galera_new_cluster
This starts MariaDB and initializes the cluster.
sudo mariadb -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
Should show 1.
Step 7: Start node2 and node3
On node2:
sudo systemctl start mariadb
Wait. Node copies database from node1 (SST via mariabackup).
sudo mariadb -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
Should show 2.
Same on node3:
sudo systemctl start mariadb
sudo mariadb -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
Should show 3.
Step 8: Verify replication
On node1:
CREATE DATABASE test;
USE test;
CREATE TABLE foo (id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(100));
INSERT INTO foo (msg) VALUES ('Hello from node1');
On node2 and node3:
USE test;
SELECT * FROM foo;
Data present everywhere, real-time.
Write on node2:
INSERT INTO foo (msg) VALUES ('Hello from node2');
SELECT * FROM foo;
All writes visible on all 3 nodes.
Step 9: Detailed status
SHOW STATUS LIKE 'wsrep_%';
Important variables:
wsrep_cluster_size: nodes UPwsrep_cluster_status: Primary (OK) / non-Primary (split-brain)wsrep_connected: ONwsrep_ready: ONwsrep_local_state_comment: Synced (OK)
Step 10: Failover
Stop a node:
sudo systemctl stop mariadb
On others:
SHOW STATUS LIKE 'wsrep_cluster_size'; -- 2
Cluster still works. Writes continue. On restart, downed node auto-catches up (IST if few changes, SST otherwise).
⚠️ If you lose 2 of 3 nodes, the remaining one goes non-Primary (writes refused) to avoid split-brain. Force bootstrap:
sudo mariadb -e "SET GLOBAL wsrep_provider_options='pc.bootstrap=YES';"
Step 11: Load balancer in front
/etc/haproxy/haproxy.cfg:
frontend galera_front
bind *:3306
mode tcp
default_backend galera_back
backend galera_back
mode tcp
balance leastconn
option httpchk
server node1 10.0.0.1:3306 check port 9200 inter 2s
server node2 10.0.0.2:3306 check port 9200 inter 2s
server node3 10.0.0.3:3306 check port 9200 inter 2s
For HTTP healthcheck, install xinetd + clustercheck on each node.
Step 12: Backups
Classic MariaDB backups work on Galera. Backup from one specific node (e.g. node3) to avoid loading write nodes.
sudo mariadb-backup --backup --target-dir=/var/backups/mariadb-$(date +%F) --user=root
Or mysqldump:
sudo mysqldump --all-databases --single-transaction | gzip > /var/backups/all-$(date +%F).sql.gz
Troubleshooting
"WSREP: Failed to open channel"
Network blocked:
nc -zv 10.0.0.2 4567
nc -zv 10.0.0.2 4444
SST fails
Check sstuser credentials and that mariabackup is installed everywhere:
sudo apt install -y mariadb-backup
Split-brain (non-Primary)
Cluster lost quorum. If majority down, restore nodes or force bootstrap on the most up-to-date one:
SHOW STATUS LIKE 'wsrep_last_committed';
Node with highest value is most up-to-date.
Degraded performance
Galera adds latency (sync). Group small transactions. Set innodb_flush_log_at_trx_commit=2 (less safe but faster).
Useful commands
sudo mariadb -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
sudo mariadb -e "SHOW STATUS LIKE 'wsrep_local_state_comment';"
sudo mariadb -e "SHOW STATUS LIKE 'wsrep_%';"
sudo galera_new_cluster
sudo systemctl start mariadb
sudo tail -f /var/log/mysql/error.log
sudo ss -tunlp | grep -E '3306|4444|4567|4568'
Conclusion
Galera Cluster provides:
- Synchronous multi-master
- Automatic failover
- Distributed reads and writes
Limits:
- Write latency = inter-node network
- InnoDB tables only
- 3 nodes min to avoid split-brain
Going further:
- Use HAProxy or ProxySQL in front for single endpoint
- Combine with MaxScale for intelligent routing
- For multi-DC, check Galera segments docs
Resources
- Official Galera docs: https://galeracluster.com/library/
- MariaDB Galera docs: https://mariadb.com/kb/en/galera-cluster/
- HAProxy: https://www.haproxy.com/documentation
- ProxySQL: https://proxysql.com

















