Implement MariaDB connection pooling with ProxySQL for high availability

Intermediate 45 min Apr 12, 2026 42 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up ProxySQL as a connection pooling proxy for MariaDB to improve performance and provide high availability. Configure backend server management, connection pooling rules, and monitoring for production workloads.

Prerequisites

  • Root or sudo access
  • At least 2GB RAM
  • Two or more MariaDB servers
  • Network connectivity between servers

What this solves

ProxySQL acts as a high-performance connection pooler and load balancer for MariaDB, reducing connection overhead and providing automatic failover. This setup improves application performance by reusing database connections and distributes queries across multiple MariaDB backend servers for high availability.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions of all components.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install ProxySQL

ProxySQL is available through official repositories and provides connection pooling and query routing capabilities.

wget https://github.com/sysown/proxysql/releases/download/v2.5.5/proxysql_2.5.5-ubuntu22_amd64.deb
sudo dpkg -i proxysql_2.5.5-ubuntu22_amd64.deb
sudo apt install -f
wget https://github.com/sysown/proxysql/releases/download/v2.5.5/proxysql-2.5.5-1-centos8.x86_64.rpm
sudo dnf install -y proxysql-2.5.5-1-centos8.x86_64.rpm

Install MariaDB client tools

Install MariaDB client to connect to ProxySQL admin interface and backend databases.

sudo apt install -y mariadb-client
sudo dnf install -y mariadb

Start and enable ProxySQL

Enable ProxySQL to start automatically on boot and start the service now.

sudo systemctl enable --now proxysql
sudo systemctl status proxysql

Access ProxySQL admin interface

ProxySQL provides an admin interface on port 6032 with default credentials. Change the password immediately after first login.

mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='ProxySQL Admin> '

Configure admin credentials

Update the default admin password for security. Replace 'NewSecurePassword123!' with your chosen password.

UPDATE global_variables SET variable_value='admin:NewSecurePassword123!' WHERE variable_name='admin-admin_credentials';
LOAD ADMIN VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;

Add MariaDB backend servers

Configure your MariaDB backend servers in the mysql_servers table. This example adds two MariaDB servers with the primary having higher weight.

INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, comment) VALUES
(0, '203.0.113.10', 3306, 1000, 'Primary MariaDB Server'),
(0, '203.0.113.11', 3306, 900, 'Secondary MariaDB Server');

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

Create MySQL users for ProxySQL

Configure database users that ProxySQL will use to connect to backend servers. These users need appropriate permissions on your MariaDB servers.

INSERT INTO mysql_users(username, password, default_hostgroup, comment) VALUES
('appuser', 'AppUserPassword123!', 0, 'Application database user'),
('readonly', 'ReadOnlyPassword123!', 1, 'Read-only user');

LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

Configure connection pooling settings

Set optimal connection pooling parameters based on your application load and server resources.

UPDATE global_variables SET variable_value='250' WHERE variable_name='mysql-max_connections';
UPDATE global_variables SET variable_value='10' WHERE variable_name='mysql-default_max_connections';
UPDATE global_variables SET variable_value='1000' WHERE variable_name='mysql-default_max_latency_ms';
UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-monitor_enabled';

LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

Set up query routing rules

Configure query rules to route SELECT queries to read replicas and write queries to the primary server. This improves performance by distributing read load.

INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply, comment) VALUES
(1, 1, '^SELECT.*', 1, 1, 'Route SELECT to read hostgroup'),
(2, 1, '^INSERT|^UPDATE|^DELETE|^CREATE|^ALTER|^DROP', 0, 1, 'Route writes to primary hostgroup');

LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

Configure health monitoring

Set up ProxySQL to monitor backend server health and automatically handle failover when servers become unavailable.

UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-monitor_connect_interval';
UPDATE global_variables SET variable_value='120000' WHERE variable_name='mysql-monitor_ping_interval';
UPDATE global_variables SET variable_value='600' WHERE variable_name='mysql-monitor_connect_timeout';
UPDATE global_variables SET variable_value='3' WHERE variable_name='mysql-monitor_ping_max_failures';

LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

Configure monitoring credentials

Set up monitoring user credentials that ProxySQL uses to check backend server health. Create this user on all MariaDB backend servers.

UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='MonitorPassword123!' WHERE variable_name='mysql-monitor_password';

LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

Create users on MariaDB backend servers

Connect to each MariaDB backend server and create the required users. Run these commands on all your MariaDB servers.

mysql -u root -p

CREATE USER 'appuser'@'%' IDENTIFIED BY 'AppUserPassword123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'%';

CREATE USER 'readonly'@'%' IDENTIFIED BY 'ReadOnlyPassword123!';
GRANT SELECT ON myapp.* TO 'readonly'@'%';

CREATE USER 'monitor'@'%' IDENTIFIED BY 'MonitorPassword123!';
GRANT REPLICATION CLIENT, PROCESS ON . TO 'monitor'@'%';

FLUSH PRIVILEGES;

Configure ProxySQL systemd service

Create a custom systemd service configuration to ensure ProxySQL starts with optimal settings and proper logging.

[Service]
LimitNOFILE=102400
OOMScoreAdjust=-900
Restart=always
RestartSec=10
sudo mkdir -p /etc/systemd/system/proxysql.service.d
sudo systemctl daemon-reload
sudo systemctl restart proxysql

Configure connection pooling optimization

Set up hostgroup configuration

Configure separate hostgroups for read and write operations to implement read/write splitting effectively.

mysql -u admin -pNewSecurePassword123! -h 127.0.0.1 -P6032

INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, comment) VALUES
(1, '203.0.113.10', 3306, 1000, 'Primary for reads'),
(1, '203.0.113.11', 3306, 1000, 'Secondary for reads');

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

Configure advanced pooling parameters

Fine-tune connection pooling settings for optimal performance based on your application's connection patterns.

UPDATE global_variables SET variable_value='20' WHERE variable_name='mysql-free_connections_pct';
UPDATE global_variables SET variable_value='8' WHERE variable_name='mysql-connection_max_age_ms';
UPDATE global_variables SET variable_value='3600000' WHERE variable_name='mysql-connection_max_age_ms';
UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-reset_connection_algorithm';

LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

Enable ProxySQL web interface

Configure the web statistics interface for monitoring connection pool performance and query metrics.

UPDATE global_variables SET variable_value='true' WHERE variable_name='admin-web_enabled';
UPDATE global_variables SET variable_value='6080' WHERE variable_name='admin-web_port';

LOAD ADMIN VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;

Monitor and optimize performance

Set up connection monitoring

Configure ProxySQL to track connection pool metrics and query performance for optimization insights.

UPDATE global_variables SET variable_value='true' WHERE variable_name='admin-stats_mysql_connections';
UPDATE global_variables SET variable_value='true' WHERE variable_name='admin-stats_mysql_query_rules';
UPDATE global_variables SET variable_value='60' WHERE variable_name='admin-stats_mysql_query_digest_to_disk';

LOAD ADMIN VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;

Create monitoring queries

Set up useful monitoring queries to track connection pool efficiency and identify performance bottlenecks.

-- Connection pool status
SELECT hostgroup,srv_host,srv_port,status,ConnUsed,ConnFree,ConnOK,ConnERR,MaxConnUsed,Queries,Bytes_data_sent,Bytes_data_recv FROM stats_mysql_connection_pool;

-- Query performance stats
SELECT hostgroup,schemaname,username,digest_text,count_star,first_seen,last_seen,sum_time,min_time,max_time FROM stats_mysql_query_digest ORDER BY sum_time DESC LIMIT 10;

-- Server health status
SELECT hostname,port,status,weight,compression,max_connections,max_replication_lag,use_ssl,max_latency_ms,comment FROM mysql_servers;

Verify your setup

# Check ProxySQL service status
sudo systemctl status proxysql

Test connection to ProxySQL

mysql -u appuser -pAppUserPassword123! -h 127.0.0.1 -P6033 -e "SELECT @@hostname;"

Check connection pool stats

mysql -u admin -pNewSecurePassword123! -h 127.0.0.1 -P6032 -e "SELECT * FROM stats_mysql_connection_pool;"

Verify backend server status

mysql -u admin -pNewSecurePassword123! -h 127.0.0.1 -P6032 -e "SELECT hostgroup_id,hostname,port,status,weight FROM mysql_servers;"

Common issues

SymptomCauseFix
Connection refused on port 6033ProxySQL not started or firewall blockingsudo systemctl start proxysql and check firewall rules
Backend servers showing OFFLINEMonitor user lacks permissionsGrant REPLICATION CLIENT to monitor user on all backends
Queries not being routed correctlyQuery rules not appliedLOAD MYSQL QUERY RULES TO RUNTIME;
Connection pool exhaustionMax connections too lowIncrease mysql-max_connections variable
High connection latencyBackend server overloadedAdd more backend servers or adjust weights
Authentication failuresUser credentials mismatchVerify mysql_users table matches backend users

Next steps

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle high availability infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.