Back to tutorials
Tutorial

MariaDB Galera Cluster Load Balancing Tutorial: Complete HAProxy and ProxySQL Configuration for Multi-Master VPS Deployment in 2026

Master MariaDB Galera cluster load balancing with HAProxy and ProxySQL. Complete tutorial for multi-master VPS deployment and failover.

By Anurag Singh
Updated on May 24, 2026
Category: Tutorial
Share article
MariaDB Galera Cluster Load Balancing Tutorial: Complete HAProxy and ProxySQL Configuration for Multi-Master VPS Deployment in 2026

Understanding MariaDB Galera Cluster Load Balancing Architecture

MariaDB Galera cluster load balancing distributes database connections across multiple nodes. This maximizes performance and ensures high availability.

Unlike traditional master-slave setups, Galera's multi-master architecture needs specialized load balancing strategies. These strategies must understand node synchronization status. They must also handle read-write conflicts intelligently.

Proper load balancing prevents connection overload on individual nodes. It also provides automatic failover when cluster members become unavailable.

Your applications maintain database connectivity even during node maintenance or unexpected failures.

This tutorial covers HAProxy and ProxySQL configuration for production MariaDB Galera clusters. You'll implement health checking, connection routing, and failover automation on your HostMyCode VPS infrastructure.

Prerequisites and Environment Setup

You need a functioning MariaDB Galera cluster with at least three nodes. Each node should run MariaDB 10.11.x or newer with wsrep provider configured.

Verify cluster status before implementing load balancers.

Check your cluster state on each node:

mysql -u root -p -e "SHOW STATUS LIKE 'wsrep%';"

Look for wsrep_cluster_size matching your node count. Check that wsrep_local_state_comment shows "Synced" on all members.

Document each node's IP address and MariaDB port (typically 3306).

Install load balancer software on dedicated servers or existing cluster nodes. HAProxy provides layer-4 load balancing. ProxySQL offers MySQL protocol-aware routing with advanced query analysis.

HAProxy Configuration for Galera Load Balancing

HAProxy excels at TCP-level load balancing with robust health checking. Install HAProxy on Ubuntu or AlmaLinux:

# Ubuntu/Debian
sudo apt update && sudo apt install haproxy -y

# AlmaLinux/RHEL
sudo dnf install haproxy -y

Create the HAProxy configuration file at /etc/haproxy/haproxy.cfg:

global
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option dontlognull

listen galera_cluster
    bind *:3307
    mode tcp
    balance leastconn
    option mysql-check user haproxy_check
    
    server galera1 10.0.1.10:3306 check port 3306 inter 2000 rise 3 fall 5
    server galera2 10.0.1.11:3306 check port 3306 inter 2000 rise 3 fall 5
    server galera3 10.0.1.12:3306 check port 3306 inter 2000 rise 3 fall 5

listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 30s
    stats admin if TRUE

Replace the IP addresses with your actual Galera node addresses. The configuration creates a TCP load balancer on port 3307.

It distributes connections using least-connection balancing.

Galera-Aware Health Checking Setup

Standard MySQL health checks ignore Galera synchronization states. Create a dedicated health check user on each cluster node:

mysql -u root -p
CREATE USER 'haproxy_check'@'%';
FLUSH PRIVILEGES;

This user needs no privileges since HAProxy only tests connection establishment.

Create an advanced health check script for Galera-specific status monitoring:

#!/bin/bash
# /usr/local/bin/galera_check.sh

MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
MYSQL_USERNAME="haproxy_check"

# Check if MySQL is running and accepting connections
mysql -h$MYSQL_HOST -P$MYSQL_PORT -u$MySQL_USERNAME -e "SELECT 1;" > /dev/null 2>&1
if [ $? -ne 0 ]; then
    exit 1
fi

# Check Galera cluster state
STATE=$(mysql -h$MYSQL_HOST -P$MYSQL_PORT -u$MYSQL_USERNAME -e "SHOW STATUS LIKE 'wsrep_local_state';" -s -N 2>/dev/null | awk '{print $2}')

# State 4 = Synced, State 2 = Donor/Desynced
if [ "$STATE" == "4" ]; then
    exit 0
else
    exit 1
fi

Make the script executable and configure xinetd or systemd to run it as a service on port 9200.

This provides HAProxy with Galera-aware health information beyond basic connection testing.

ProxySQL Configuration for Advanced Query Routing

ProxySQL offers MySQL protocol-aware load balancing with query routing, connection pooling, and detailed monitoring.

Install ProxySQL from the official repository:

# Add ProxySQL repository
wget -O - 'https://repo.proxysql.com/ProxySQL/repo_pub_key' | apt-key add -
echo deb https://repo.proxysql.com/ProxySQL/proxysql-2.5.x/$(lsb_release -sc)/ ./ | tee /etc/apt/sources.list.d/proxysql.list

# Install ProxySQL
sudo apt update && sudo apt install proxysql -y

Start ProxySQL and access the admin interface:

sudo systemctl start proxysql
sudo systemctl enable proxysql

# Connect to admin interface
mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '

Configure your Galera nodes as backend servers. ProxySQL uses hostgroups to organize servers by function:

-- Configure backend servers
INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, comment) VALUES
(0, '10.0.1.10', 3306, 900, 'galera1'),
(0, '10.0.1.11', 3306, 900, 'galera2'),
(0, '10.0.1.12', 3306, 900, 'galera3');

-- Load server configuration
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

Create database users for application connections. ProxySQL requires users to be defined in its configuration:

-- Add application users
INSERT INTO mysql_users(username, password, default_hostgroup, max_connections) VALUES
('app_user', 'secure_password', 0, 200);

-- Load user configuration
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

Advanced Query Routing and Read-Write Splitting

ProxySQL can route queries based on patterns. This enables sophisticated load distribution.

Configure separate hostgroups for different query types:

-- Create hostgroups for different query types
INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, comment) VALUES
(1, '10.0.1.10', 3306, 900, 'galera1-read'),
(1, '10.0.1.11', 3306, 900, 'galera2-read'),
(1, '10.0.1.12', 3306, 900, 'galera3-read');

-- Configure query routing rules
INSERT INTO mysql_query_rules(active, match_pattern, destination_hostgroup, apply) VALUES
(1, '^SELECT.*FOR UPDATE', 0, 1),
(1, '^SELECT.*', 1, 1),
(1, '^INSERT.*|^UPDATE.*|^DELETE.*', 0, 1);

-- Load routing rules
LOAD MYSQL QUERY_RULES TO RUNTIME;
SAVE MYSQL QUERY_RULES TO DISK;

This configuration sends SELECT queries to hostgroup 1. It directs writes and SELECT FOR UPDATE to hostgroup 0.

You can customize routing rules based on your application's query patterns.

Monitor query routing effectiveness through ProxySQL's statistics tables:

-- View query routing statistics
SELECT hostgroup, sum_time, count_star FROM stats_mysql_commands_counters 
WHERE Total_Time_us > 0 ORDER BY sum_time DESC;

Connection Pooling and Performance Optimization

Configure ProxySQL's connection pooling to optimize resource usage. Proper pooling reduces connection overhead and improves cluster performance:

-- Configure connection pooling per hostgroup
UPDATE mysql_servers SET 
    max_connections = 300,
    use_ssl = 0,
    max_replication_lag = 5
WHERE hostgroup_id IN (0,1);

-- Set global connection limits
UPDATE global_variables SET variable_value = '4096' 
WHERE variable_name = 'mysql-max_connections';

UPDATE global_variables SET variable_value = '300' 
WHERE variable_name = 'mysql-default_max_connections';

-- Apply configuration changes
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

Monitor connection pool utilization to identify bottlenecks:

SELECT hostgroup, srv_host, ConnUsed, ConnFree, ConnOK, ConnERR 
FROM stats_mysql_connection_pool ORDER BY hostgroup, srv_host;

Adjust pool sizes based on your application's connection patterns. Applications with many short-lived connections benefit from larger pools.

Long-running connections need fewer pooled connections.

Implementing Automatic Failover Logic

Configure automatic failover to handle node failures gracefully. HAProxy provides basic failover through health checks.

ProxySQL offers more sophisticated failure detection.

Set up HAProxy failover thresholds in your configuration:

server galera1 10.0.1.10:3306 check port 3306 inter 2000 rise 3 fall 5 weight 100
server galera2 10.0.1.11:3306 check port 3306 inter 2000 rise 3 fall 5 weight 100  
server galera3 10.0.1.12:3306 check port 3306 inter 2000 rise 3 fall 5 weight 90 backup

The rise 3 fall 5 parameters require 3 successful checks to mark a server healthy. They need 5 failed checks to mark it down.

The backup directive makes galera3 a standby node.

For ProxySQL, implement custom failover scripts that monitor cluster health:

#!/bin/bash
# /usr/local/bin/proxysql_failover.sh

# Check cluster size and adjust ProxySQL configuration
CLUSTER_SIZE=$(mysql -h127.0.0.1 -P6033 -uapp_user -p$DB_PASS -e "SELECT @@wsrep_cluster_size;" -s -N 2>/dev/null)

if [ "$CLUSTER_SIZE" -lt 2 ]; then
    # Disable load balancing when cluster size drops below 2
    mysql -h127.0.0.1 -P6032 -uadmin -padmin -e "UPDATE mysql_servers SET status='OFFLINE_HARD' WHERE hostgroup_id=1;"
    mysql -h127.0.0.1 -P6032 -uadmin -padmin -e "LOAD MYSQL SERVERS TO RUNTIME;"
fi

Run this script via cron every minute to maintain cluster availability during partial failures.

Load Balancer Monitoring and Troubleshooting

Implement comprehensive monitoring to track load balancer performance. HAProxy provides detailed statistics through its web interface and socket commands:

# Check HAProxy statistics via socket
echo "show stat" | sudo socat - /run/haproxy/admin.sock | grep galera

# View current connections
echo "show sess" | sudo socat - /run/haproxy/admin.sock

Monitor ProxySQL performance through its statistics schema:

-- Monitor connection pool performance
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree, Latency_us
FROM stats_mysql_connection_pool;

-- Check query response times
SELECT hostgroup, schemaname, username, client_addr, command, 
       time_start_us, match_digest, match_pattern
FROM stats_mysql_processlist 
WHERE time_start_us > UNIX_TIMESTAMP(NOW() - INTERVAL 1 MINUTE) * 1000000;

Set up alerting for critical metrics like connection pool exhaustion, high query latency, or node failures.

Many organizations integrate these metrics with monitoring solutions like Prometheus or Zabbix.

For detailed query analysis and performance troubleshooting, refer to our database query execution plan analysis guide for advanced optimization techniques.

Ready to deploy MariaDB Galera clusters with professional load balancing? HostMyCode's managed VPS hosting provides the resources and support needed for high-availability database deployments. Our team can assist with Galera cluster setup and load balancer configuration.

Frequently Asked Questions

How do I choose between HAProxy and ProxySQL for MariaDB Galera load balancing?

Choose HAProxy for simple TCP load balancing with minimal overhead. Use ProxySQL when you need MySQL protocol awareness, query routing, connection pooling, or detailed monitoring. ProxySQL offers more database-specific features but requires more configuration.

What's the recommended number of load balancer instances?

Deploy at least two load balancer instances for high availability. Use keepalived or similar tools to provide VIP failover between load balancers. Avoid single points of failure in your load balancing layer.

How do I handle split-brain scenarios with load balancers?

Configure your load balancers to check cluster size before routing traffic. Implement minimum cluster size requirements (typically 50% + 1 of total nodes) before accepting connections. Use Galera's pc.bootstrap parameter to handle split-brain recovery.

Can I use both HAProxy and ProxySQL together?

Yes, you can use HAProxy for high-availability failover between multiple ProxySQL instances. This provides both database-aware routing and load balancer redundancy. Configure HAProxy to balance connections across multiple ProxySQL servers.

What are the key metrics to monitor for MariaDB Galera cluster load balancing?

Monitor connection pool utilization, query response times, cluster size, node synchronization status, and load balancer health check success rates. Set up alerts for connection pool exhaustion, high query latency, and cluster state changes.