ProxySQL真香 ,老板再也不叫我修改mysql主节点配置

介绍一下基本概念

🤔基于上文配置的MGR会出现一个问题

虽然我们配置完mgr实现了主从切换,主节点负责写,主从节点都可读 但是由于mgr的特性,主节点宕机之后会自动选举新的主节点,此时我们应用的mysql配置就存在需要修改的情况,频繁的去修改配置重启肯定是不实际的,在生产环境这么搞,估计老板晚上都睡不好了!

为了解决这个问题,proxysql是的香!!!

proxysql是什么:

proxysql是实现数据库负载均衡和流量路由的工具,是在应用服务和mysql服务之间的一个代理层,应用服务通过配置proxysql节点的ip+端口,实现访问mysql的多个节点

传统方式

sequenceDiagram 应用服务->>MYSQL服务: 配置MYSQL节点ip+port,单节点没问题,主从节点则需要多个配置,对于mgr,一旦出现主节点宕机,需要频繁修改ip+port

使用proxysql代理

sequenceDiagram 应用->>proxysql: 配置proxysql节点ip+port,通过proxysql的ip,解决mgr集群主节点宕机需要修改配置的问题,proxysql会自动帮我们代理到正确的节点上 proxysql->>mysql服务: 通过配置在proxysql内置数据库中的多个mysql节点的信息实现proxysql动态代理多个主从节点

接下来让我手把手教你如何配置最基本的proxysql+mgr

还没有配置mgr的同学可移步到上一章节

首先进行规划

节点1 节点2 节点3
172.28.15.52 172.28.5.229 172.28.2.171

首先是安装proxysql,这个在任何节点安装都可以,我们选择在节点1安装,后续统一使用节点1、2、3称呼

注:6032 是 ProxySal的管理端口号,6033 是对外服务的端口号

这个是proxysql的下载地址,下载地址 github.com/sysown/prox... 下载完成之后直接上传,用命令安装,这块比较容易不做过多解释

yum localinstall proxysql-2.3.2-1-centos8.x86 64.rpm

启动proxysql

sql 复制代码
启动
systemctl start proxysql

启动之后开始我们的重头戏 首先我们使用命令登录到proxysql内置的mysql中

css 复制代码
在节点1,即proxysql的节点上,使用6032管理端口访问,6033是对外的端口
mysql -uadmin -padmin -h127.0.0.1 -P 6032

将我们的mgr集群三台节点的信息存到proxysql中

sql 复制代码
insert into mysql_servers(hostgroup_id,hostname,port) values
(10,'节点1'3306);
insert into mysql_servers(hostgroup_id,hostname,port) values
(10,'节点2'3306);
insert into mysql_servers(hostgroup_id,hostname,port) values
(10,'节点3'3306);
css 复制代码
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

然后我们创建两个用户,monitor和proxysql,monitor用于proxysql去监控我们集群的状态,proxysql用于给我们的应用服务配置访问proxysql

sql 复制代码
这一块的命令在我们mgr集群的主节点上使用
CREATE USER 'monitor'@'%' IDENTIFlED with mysql_native_password By "monitor@2021";
CREATE USER 'proxysql'@'%' IDENTIFlED with mysql_native_password By "proxysql@2021";
GRANT ALL PRIVILEGES ON *.* TO 'monitor'@'%';
GRANT ALL PRIVILEGES ON *.* TO 'proxysq!'@'%';
flush privileges;

然后回到我们proxysql的终端中操作,这块是设置监控账号以及给proxysql插入能够访问mgr的账号

less 复制代码
set mysql-monitor_username='monitor' ;
set mysal-monitor_password='monitor@2021';
Insert into mysql_users(username,password,active,default_hostgroup,transaction_persistent)
values('proxysql',proxysql@2021',1,10,1);

接下来是重重重头戏,在mgr主节点创建视图,用于监控账号访问,使proxysql能够监听到mgr的状态

sql 复制代码
USE sys;

DROP VIEW IF EXISTS gr_member_routing_candidate_status;
DROP FUNCTION IF EXISTS IFZERO;
DROP FUNCTION IF EXISTS LOCATE2;
DROP FUNCTION IF EXISTS GTID_NORMALIZE;
DROP FUNCTION IF EXISTS GTID_COUNT;
DROP FUNCTION IF EXISTS gr_applier_queue_length;
DROP FUNCTION IF EXISTS gr_member_in_primary_partition;
DROP FUNCTION IF EXISTS gr_transactions_to_cert;
DROP FUNCTION IF EXISTS my_server_uuid;

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_transactions_to_cert () RETURNS INT ( 11 ) DETERMINISTIC BEGIN
	RETURN ( SELECT `performance_schema`.replication_group_member_stats.COUNT_TRANSACTIONS_IN_QUEUE AS transactions_to_cert FROM `performance_schema`.replication_group_member_stats WHERE MEMBER_ID = @@SERVER_UUID );
	
END $$ CREATE FUNCTION my_server_uuid () RETURNS TEXT ( 36 ) DETERMINISTIC NO SQL RETURN ( SELECT @@GLOBAL.server_uuid AS my_id );
CREATE VIEW gr_member_routing_candidate_status AS SELECT
IFNULL(
	(
		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 = my_server_uuid ()),
		'No' 
	) AS viable_candidate,
	IFNULL(`sys`.gr_applier_queue_length(), 0 ) AS transactions_behind,
	IFNULL(`sys`.gr_transactions_to_cert(), 0 ) AS transactions_to_cert,
IF
(	
		(
		SELECT((select 
			GROUP_CONCAT( `performance_schema`.global_variables.VARIABLE_VALUE SEPARATOR ',' ) 
		FROM
			`performance_schema`.global_variables 
		WHERE
			(
			`performance_schema`.global_variables.VARIABLE_NAME IN ( 'read_only', 'super_read_only' ))) != 'OFF,OFF' 
		)) ,
		'YES',
		'No' 
	) AS read_only;$$
 DELIMITER;

最后面的view可能会执行报错,不用管,只要保证最后一个view有建起来即可

下面这个命令在mgr中执行 如果视图和function都创建成功是可以查询出这个的

csharp 复制代码
在mgr中执行查询语句
select * from sys.gr_member_routing_candidate_status;

接下来我们回到proxysql终端操作

首先设置读写组
sql 复制代码
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,100);

执行语句将配置都刷新proxysql

css 复制代码
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

proxysql执行语句,此时可以看到,proxysql查询到了我们的mgr集群,10、20、30、40是我们设置的主写,备写,主读,备读的组id,

sql 复制代码
select hostgroup_id, hostname, port,status from runtime_mysql_servers;

此时可以停掉主节点,看这个语句是否改变,我们执行systemctl stop mysqld,停掉我们的mgr主节点 此时可以看到监控到了节点挂了,并且52节点变成了10,主写节点

执行命令查看节点情况

sql 复制代码
select  hostname,                   port,                    viable_candidate,                 read_only,                   transactions_behind,                    error             from mysql_server_group_replication_log             order by time_start_us desc           limit 6;

接下来我们要配置读写分离规则,这个语句不要输入错了,否则无法对我们写的sql进行读写代理

sql 复制代码
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply)VALUES (1, 1, '^SELECT.*FOR UPDATES$', 10, 1),(2, 1, '^SELECT', 30, 1);

加载配置

css 复制代码
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

接下来我们在任意一台节点访问proxysql的对外6033端口

css 复制代码
mysql -u proxysql -p'xxxx' -P 6033 -h172.28.15.52  -e 'select user,host from mysql.user where 1=1;'

在proxysql中执行查询语句,查看路由的情况,我们查看到查询语句被转发到读节点上,组id为30代表主读节点组

csharp 复制代码
select hostgroup,digest_text,username from stats_mysql_query_digest;

执行建表语句可以看到是代理到了主节点上

sql 复制代码
CREATE TABLE `mgrtest2` (
  `id` int NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=231232 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

至此我们就完成了proxysql对mgr集群的代理和监控,我们只需要在我们的应用服务配置proxysql节点的ip+6033端口,使用proxysql这个用户,或者自己建一个新用户,授权,并且把这个用户配置到proxysql中,即可实现访问proxysql代理到mgr,注意6032为proxysql的内部端口,只有admin/admin可访问。6033为对外端口

ps,上述有不正确的地方欢迎各位客官指正,共同进步

相关推荐
Python私教2 小时前
model中能定义字段声明不存储到数据库吗
数据库·oracle
BestandW1shEs4 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师4 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球4 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...4 小时前
表的操作(MySQL)
数据库·mysql·表的操作
哥谭居民00014 小时前
MySQL的权限管理机制--授权表
数据库
wqq_9922502774 小时前
ssm旅游推荐系统的设计与开发
数据库·旅游
难以触及的高度5 小时前
mysql中between and怎么用
数据库·mysql
Jacky(易小天)5 小时前
MongoDB比较查询操作符中英对照表及实例详解
数据库·mongodb·typescript·比较操作符