官方文档
https://proxysql.com/documentation/ProxySQL-Configuration/
下载安装proxysql
https://github.com/sysown/proxysql/releases/download/v2.6.0/proxysql-2.6.0-1-centos7.x86_64.rpm
yum -y localinstall proxysql-2.6.0-1-centos7.x86_64.rpm
# 软链接数据目录
rm -rf /var/lib/proxysql/
mkdir -p /data/proxysql
ln -s /data/proxysql/ /var/lib/
chown -R proxysql.proxysql /var/lib/proxysql/
chown -R proxysql.proxysql /var/lib/proxysql
# 启动proxysql
systemctl start proxysql
systemctl status proxysql
systemctl enable proxysql
防火墙放行
firewall-cmd --permanent --zone=public --add-port={6032..6033}/tcp && firewall-cmd --reload
下载安装mysql客户端
tar -zxvf mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar.gz
rpm -ivh mysql-community-client-8.0.19-1.el7.x86_64.rpm --nodeps --force
连接proxy管理接口配置
mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '
# 确认mysql_servers、mysql_replication_hostgroups、mysql_query_rules三张表的配置是否为空
SELECT * FROM mysql_servers;
SELECT * from mysql_replication_hostgroups;
SELECT * from mysql_query_rules;
proxysql添加后端mysql
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (10,'192.168.200.31',3308);
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (10,'192.168.200.32',3308);
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (10,'192.168.200.33',3308);
load mysql servers to runtime;
save mysql servers to disk;
MGR集群主节点添加监控账号
create user 'monitor'@'192.168.200.%' identified with mysql_native_password by 'UBXWlwDw4X93s%#GtXyx';
GRANT SELECT on sys.* to 'monitor'@'192.168.200.%';
GRANT SELECT on performance_schema.* to 'monitor'@'192.168.200.%';
proxysql添加设置监控账号
UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='UBXWlwDw4X93s%#GtXyx' WHERE variable_name='mysql-monitor_password';
load mysql variables to runtime;
save mysql variables to disk;
MGR集群主节点添加监控视图
# addition_to_sys.sql MGR创建监控视图sql文件
https://lefred.be/content/mysql-group-replication-native-support-in-proxysql/
cat > addition_to_sys.sql << EOF
USE sys;
DELIMITER $$
CREATE FUNCTION IFZERO(a INT, b INT)
RETURNS INT
DETERMINISTIC
RETURN IF(a = 0, b, a)$$
CREATE FUNCTION LOCATE2(needle TEXT(10000), haystack TEXT(10000), offset INT)
RETURNS INT
DETERMINISTIC
RETURN IFZERO(LOCATE(needle, haystack, offset), LENGTH(haystack) + 1)$$
CREATE FUNCTION GTID_NORMALIZE(g TEXT(10000))
RETURNS TEXT(10000)
DETERMINISTIC
RETURN GTID_SUBTRACT(g, '')$$
CREATE FUNCTION GTID_COUNT(gtid_set TEXT(10000))
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE result BIGINT DEFAULT 0;
DECLARE colon_pos INT;
DECLARE next_dash_pos INT;
DECLARE next_colon_pos INT;
DECLARE next_comma_pos INT;
SET gtid_set = GTID_NORMALIZE(gtid_set);
SET colon_pos = LOCATE2(':', gtid_set, 1);
WHILE colon_pos != LENGTH(gtid_set) + 1 DO
SET next_dash_pos = LOCATE2('-', gtid_set, colon_pos + 1);
SET next_colon_pos = LOCATE2(':', gtid_set, colon_pos + 1);
SET next_comma_pos = LOCATE2(',', gtid_set, colon_pos + 1);
IF next_dash_pos < next_colon_pos AND next_dash_pos < next_comma_pos THEN
SET result = result +
SUBSTR(gtid_set, next_dash_pos + 1,
LEAST(next_colon_pos, next_comma_pos) - (next_dash_pos + 1)) -
SUBSTR(gtid_set, colon_pos + 1, next_dash_pos - (colon_pos + 1)) + 1;
ELSE
SET result = result + 1;
END IF;
SET colon_pos = next_colon_pos;
END WHILE;
RETURN result;
END$$
CREATE FUNCTION gr_applier_queue_length()
RETURNS INT
DETERMINISTIC
BEGIN
RETURN (SELECT sys.gtid_count( GTID_SUBTRACT( (SELECT
Received_transaction_set FROM performance_schema.replication_connection_status
WHERE Channel_name = 'group_replication_applier' ), (SELECT
@@global.GTID_EXECUTED) )));
END$$
CREATE FUNCTION gr_member_in_primary_partition()
RETURNS VARCHAR(3)
DETERMINISTIC
BEGIN
RETURN (SELECT IF( MEMBER_STATE='ONLINE' AND ((SELECT COUNT(*) FROM
performance_schema.replication_group_members WHERE MEMBER_STATE != 'ONLINE') >=
((SELECT COUNT(*) FROM performance_schema.replication_group_members)/2) = 0),
'YES', 'NO' ) FROM performance_schema.replication_group_members JOIN
performance_schema.replication_group_member_stats USING(member_id));
END$$
CREATE VIEW gr_member_routing_candidate_status AS SELECT
sys.gr_member_in_primary_partition() as viable_candidate,
IF( (SELECT (SELECT GROUP_CONCAT(variable_value) FROM
performance_schema.global_variables WHERE variable_name IN ('read_only',
'super_read_only')) != 'OFF,OFF'), 'YES', 'NO') as read_only,
sys.gr_applier_queue_length() as transactions_behind, Count_Transactions_in_queue as 'transactions_to_cert' from performance_schema.replication_group_member_stats;$$
DELIMITER ;
EOF
cat > addition_to_sys2.sql << EOF
USE sys;
DELIMITER $$
DROP FUNCTION gr_member_in_primary_partition$$
DROP VIEW gr_member_routing_candidate_status$$
CREATE FUNCTION gr_member_in_primary_partition()
RETURNS VARCHAR(3)
DETERMINISTIC
BEGIN
RETURN (SELECT IF( MEMBER_STATE='ONLINE' AND ((SELECT COUNT(*) FROM
performance_schema.replication_group_members WHERE MEMBER_STATE != 'ONLINE') >=
((SELECT COUNT(*) FROM performance_schema.replication_group_members)/2) = 0),
'YES', 'NO' ) FROM performance_schema.replication_group_members JOIN
performance_schema.replication_group_member_stats rgms USING(member_id) WHERE rgms.MEMBER_ID=@@SERVER_UUID);
END$$
CREATE VIEW gr_member_routing_candidate_status AS SELECT
sys.gr_member_in_primary_partition() as viable_candidate,
IF( (SELECT (SELECT GROUP_CONCAT(variable_value) FROM
performance_schema.global_variables WHERE variable_name IN ('read_only',
'super_read_only')) != 'OFF,OFF'), 'YES', 'NO') as read_only,
sys.gr_applier_queue_length() as transactions_behind, Count_Transactions_in_queue as 'transactions_to_cert'
from performance_schema.replication_group_member_stats rgms
where rgms.MEMBER_ID=(select gv.VARIABLE_VALUE
from `performance_schema`.global_variables gv where gv.VARIABLE_NAME='server_uuid');$$
DELIMITER ;
EOF
加载视图sql
source /root/addition_to_sys.sql;
查看视图监控状态
select * from gr_member_routing_candidate_status;
如果报错
ERROR 1242 (21000): Subquery returns more than 1 row
source /root/addition_to_sys2.sql;
proxysql设置读写组
# 查看读写复制组表
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)
values(10,20,30,40,1,1,0,0);
load mysql servers to runtime;
save mysql servers to disk;
MGR集群状态查询
mysql> select * from sys.gr_member_routing_candidate_status;
+------------------+-----------+---------------------+----------------------+
| viable_candidate | read_only | transactions_behind | transactions_to_cert |
+------------------+-----------+---------------------+----------------------+
| YES | NO | 0 | 0 |
+------------------+-----------+---------------------+----------------------+
1 row in set (0.04 sec)
proxysql状态查询
Admin> select hostgroup_id, hostname, status from runtime_mysql_servers;
+--------------+----------------+--------+
| hostgroup_id | hostname | status |
+--------------+----------------+--------+
| 10 | 192.168.200.32 | ONLINE |
| 20 | 192.168.200.31 | ONLINE |
| 20 | 192.168.200.33 | ONLINE |
+--------------+----------------+--------+
MGR主节点创建业务账号
create user 'gadmin'@'192.168.200.%' identified with mysql_native_password by 'UBXWlwDw4X93s%#GtXyx';
GRANT all privileges on *.* to 'gadmin'@'192.168.200.%';
proxysql添加业务账号
INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('gadmin','UBXWlwDw4X93s%#GtXyx',10);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
SELECT * FROM mysql_users;
proxysql添加读写分离规则
INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (10,1,'gadmin','^SELECT.*FOR UPDATE$',10,1);
INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (20,1,'gadmin','^SELECT',30,1);
load mysql query rules to runtime;
save mysql query rules to disk;
# 查看规则
SELECT match_digest,destination_hostgroup FROM mysql_query_rules WHERE active=1 AND username='gadmin' ORDER BY rule_id;
# 查看路由状态
SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;
测试读写分离
mysql -ugadmin -p'UBXWlwDw4X93s%#GtXyx' -h192.168.200.30 -P6033 -e 'create database proxysql_mgr_test;'
mysql -ugadmin -p'UBXWlwDw4X93s%#GtXyx' -h192.168.200.30 -P6033 -e 'use proxysql_mgr_test;select * from tb01;'
mysql -ugadmin -p'UBXWlwDw4X93s%#GtXyx' -h192.168.200.30 -P6033 -e 'show databases;'
mysql -ugadmin -p'UBXWlwDw4X93s%#GtXyx' -h192.168.200.30 -P6033 -e 'drop database proxysql_mgr_test;'