ProxySQL MySQL MySQL · DBA · High Availability

ProxySQLMySQL Group Replication

Configure ProxySQL with MySQL Group Replication (MGR) in single-primary mode. Covers MGR setup, ProxySQL hostgroup config, user creation and automatic primary failover.

MySQL Group Replication (MGR) provides multi-master or single-primary replication with automatic failover and conflict detection. ProxySQL integrates with MGR through the mysql_group_replication_hostgroups table and monitors the performance_schema.replication_group_members view to track which node is primary and which are secondaries.

  Applications → ProxySQL :6033
                      │
              ┌───────┴────────┐
    Writes → HG10         Reads → HG20
              │                   │
        [Primary Node]   [Secondary Nodes]
        192.168.1.100    192.168.1.101
                         192.168.1.102

  All 3 nodes form a Group Replication cluster
  Primary accepts R/W, Secondaries are read-only
SQL — Group Replication Setup
-- in my.cnf on ALL nodes:
-- [mysqld]
-- server-id = 1                  (unique per node)
-- gtid_mode = ON
-- enforce_gtid_consistency = ON
-- binlog_checksum = NONE
-- log_slave_updates = ON
-- plugin_load_add = group_replication.so
-- group_replication_group_name = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
-- group_replication_start_on_boot = OFF
-- group_replication_local_address = "192.168.1.100:33061"
-- group_replication_group_seeds = "192.168.1.100:33061,192.168.1.101:33061,192.168.1.102:33061"
-- group_replication_bootstrap_group = OFF

-- On first node only — bootstrap the group
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

-- On other nodes:
START GROUP_REPLICATION;

-- Check group status
SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE
FROM performance_schema.replication_group_members;
SQL — Create Users
-- Run on PRIMARY node (replicates to others)

-- Monitor user
CREATE USER 'monitor'@'%' IDENTIFIED BY 'MonitorPass123!';
GRANT SELECT ON performance_schema.* TO 'monitor'@'%';
GRANT SELECT ON sys.* TO 'monitor'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'monitor'@'%';

-- App user
CREATE USER 'appuser'@'%' IDENTIFIED BY 'AppPass123!';
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'%';

FLUSH PRIVILEGES;
SQL — ProxySQL Config for MGR
-- Connect to ProxySQL Admin

-- Monitor credentials
UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='MonitorPass123!' WHERE variable_name='mysql-monitor_password';
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

-- Add ALL nodes to a single hostgroup (ProxySQL auto-sorts them)
INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, comment)
VALUES (10, '192.168.1.100', 3306, 'ONLINE', 'MGR Node 1');
INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, comment)
VALUES (10, '192.168.1.101', 3306, 'ONLINE', 'MGR Node 2');
INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, comment)
VALUES (10, '192.168.1.102', 3306, 'ONLINE', 'MGR Node 3');

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

-- Configure Group Replication hostgroups
INSERT INTO mysql_group_replication_hostgroups
  (writer_hostgroup, backup_writer_hostgroup, reader_hostgroup,
   offline_hostgroup, active, max_writers, writer_is_also_reader,
   max_transactions_behind, comment)
VALUES
  (10, 30, 20, 40, 1, 1, 0, 0, 'MGR Single Primary');

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

-- Add app user
INSERT INTO mysql_users (username, password, default_hostgroup, transaction_persistent)
VALUES ('appuser', 'AppPass123!', 10, 1);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

-- Query rules
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply, comment)
VALUES (1, 1, '^SELECT .* FOR UPDATE', 10, 1, 'Locking reads → Primary');
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply, comment)
VALUES (2, 1, '^SELECT', 20, 1, 'SELECTs → Secondaries');
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
SQL — Verify MGR Setup
-- Check how ProxySQL sorted the nodes
SELECT hostgroup_id, hostname, port, status
FROM runtime_mysql_servers
ORDER BY hostgroup_id;

-- Expected:
-- HG10: Primary node (ONLINE)
-- HG20: Secondary nodes (ONLINE)
-- HG30: backup writers (usually empty in single-primary)
-- HG40: offline/recovering nodes

-- Check ProxySQL sees MGR members
SELECT hostname, port, time_start_us, success_time_us, read_only
FROM monitor.mysql_server_read_only_log
ORDER BY time_start_us DESC LIMIT 10;

-- Test automatic failover
-- Stop the primary, ProxySQL auto-detects new primary within seconds
ColumnDescription
writer_hostgroupPrimary node goes here
backup_writer_hostgroupAdditional primaries (multi-primary mode)
reader_hostgroupSecondary nodes go here
offline_hostgroupRecovering/error nodes go here
active1 = enable auto-management
max_writersMax primary nodes (1 for single-primary)
writer_is_also_reader1 = primary also handles reads
max_transactions_behindMax transactions a secondary can be behind