数据库系列之MySQL高可用MGR故障自动切换

2024-01-19 13:48

本文主要是介绍数据库系列之MySQL高可用MGR故障自动切换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文简要测试了MGR+ProxySQL架构下的MySQL高可用架构,实现MGR架构下主节点故障时候的无感知切换。


在前文《数据库系列之MySQL组复制MGR》中介绍了MGR组复制的原理和架构,MGR组复制能够解决MySQL集群内部的故障自动转移。但是在单主模式下,业务连接的主节点发生切换的时候,应用程序并不能自动连接到新的主节点上,需要手动进行主节点切换。为了解决业务层面的故障自动转移,引入了ProxySQL组件,实现MGR架构下主节点故障时候的无感知切换。

在这里插入图片描述

如图所示,当主节点宕机后,MGR会重新选择主节点,ProxySQL能够自动探测到新的主节点,并将写数据操作路由到新的主节点,满足业务的正常写入。

1、环境准备

1)mysql基础环境
在这里插入图片描述

查看MGR状态为online

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+----------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST    | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+----------------+-------------+--------------+
| group_replication_applier | be42da32-eb35-11ea-9505-000c2937f917 | tango-centos02 |        3306 | ONLINE       |
| group_replication_applier | de623c4b-eb35-11ea-b1e4-000c2959d3e3 | tango-centos03 |        3306 | ONLINE       |
| group_replication_applier | e5fb2194-eb27-11ea-b838-000c2992e812 | tango-centos01 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+----------------+-------------+--------------+
3 rows in set (0.00 sec)

2)ProxySQL安装

参考“MySQL主从复制读写分离实现”中基于ProxySQL部分内容。启动ProxySQL:

[root@tango-01 ~]# systemctl start proxysql
[root@tango-01 ~]# netstat -nltp|grep proxysql
tcp        0      0 0.0.0.0:6032            0.0.0.0:*               LISTEN      1968/proxysql       
tcp        0      0 0.0.0.0:6033            0.0.0.0:*               LISTEN      1968/proxysql

ProxySQL是3层配置系统,包括Runtime、Memory、Disk&Configuration File:

  • Runtime层表示ProxySQL工作线程使用的内存数据结构;
  • Memory(也被称为main)层经由一个MySQL兼容接口露出的内存数据库,用户可以使用MySQL客户端连接到管理界面,查看、编辑ProxySQL配置表;
  • Disk & Configuration File。Disk层是一个存放在磁盘上的SQLite3数据库,Disk层可将内存中的配置信息保存到磁盘,以便ProxySQL重新启动后配置还可用。

简单理解就是Runtime是ProxySQL正在使用的配置信息、Memory层是用户可以编辑的信息、Disk层是把配置信息永久保存在磁盘上。

##将配置项从内存数据库加载到运行时数据结构
LOAD <item> FROM MEMORY/LOAD <item> TO RUNTIME##将配置项从运行时保存到内存数据库中
SAVE <item> TO MEMORY/SAVE <item> FROM RUNTIME##将持久性配置项目从磁盘数据库加载到内存数据库
LOAD <item> TO MEMORY/LOAD <item> FROM DISK##将配置项从内存数据库保存到磁盘数据库
SAVE <item> FROM MEMORY/SAVE <item> TO DISK##将配置项从配置文件加载到内存数据库中
LOAD <item> FROM CONFIG
2、环境配置
2.1 配置Proxysql
2.1.1 检查配置信息

登录proxysql管理端,默认端口6032,查看相关配置表是否存在信息,如果已经配置过了,可以先删除信息。

[root@tango-01 mysql]# ./bin/mysql -uadmin -padmin -h127.0.0.1 -P6032
mysql> select * from mysql_servers;
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| hostgroup_id | hostname        | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment     |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| 1            | 192.168.112.101 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Write Group |
| 2            | 192.168.112.102 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
| 2            | 192.168.112.103 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
3 rows in set (0.17 sec)mysql> select * from mysql_users;
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+---------+
| username | password | active | use_ssl | default_hostgroup | default_schema | schema_locked | transaction_persistent | fast_forward | backend | frontend | max_connections | comment |
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+---------+
| proxysql | password | 1      | 0       | 1                 | NULL           | 0             | 1                      | 0            | 1       | 1        | 10000           |         |
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+---------+
1 row in set (0.13 sec)mysql> select * from mysql_query_rules;
+---------+--------+----------+------------+--------+-------------+------------+------------+--------+----------------------+---------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+-----------+--------+-------------+-----------+---------------------+-----+-------+---------+
| rule_id | active | username | schemaname | flagIN | client_addr | proxy_addr | proxy_port | digest | match_digest         | match_pattern | negate_match_pattern | re_modifiers | flagOUT | replace_pattern | destination_hostgroup | cache_ttl | cache_empty_result | cache_timeout | reconnect | timeout | retries | delay | next_query_flagIN | mirror_flagOUT | mirror_hostgroup | error_msg | OK_msg | sticky_conn | multiplex | gtid_from_hostgroup | log | apply | comment |
+---------+--------+----------+------------+--------+-------------+------------+------------+--------+----------------------+---------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+-----------+--------+-------------+-----------+---------------------+-----+-------+---------+
| 1       | 1      | NULL     | NULL       | 0      | NULL        | NULL       | NULL       | NULL   | ^SELECT.*FOR UPDATE$ | NULL          | 0                    | CASELESS     | NULL    | NULL            | 1                     | NULL      | NULL               | NULL          | NULL      | NULL    | NULL    | NULL  | NULL              | NULL           | NULL             | NULL      | NULL   | NULL        | NULL      | NULL                | NULL | 1     | NULL    |
| 2       | 1      | NULL     | NULL       | 0      | NULL        | NULL       | NULL       | NULL   | ^SELECT              | NULL          | 0                    | CASELESS     | NULL    | NULL            | 2                     | NULL      | NULL               | NULL          | NULL      | NULL    | NULL    | NULL  | NULL              | NULL           | NULL             | NULL      | NULL   | NULL        | NULL      | NULL                | NULL | 1     | NULL    |
+---------+--------+----------+------------+--------+-------------+------------+------------+--------+----------------------+---------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+-----------+--------+-------------+-----------+---------------------+-----+-------+---------+
2 rows in set (0.12 sec)mysql> select * from mysql_group_replication_hostgroups;
Empty set (0.01 sec)mysql> delete from mysql_servers;
Query OK, 3 rows affected (0.12 sec)mysql> delete from mysql_users;
Query OK, 1 row affected (0.01 sec)mysql> delete from mysql_query_rules;
Query OK, 2 rows affected (0.00 sec)mysql> LOAD MYSQL VARIABLES TO RUNTIME;
Query OK, 0 rows affected (0.14 sec)mysql> SAVE MYSQL VARIABLES TO DISK;
Query OK, 137 rows affected (0.09 sec)mysql> LOAD MYSQL SERVERS TO RUNTIME;
Query OK, 0 rows affected (0.55 sec)mysql> SAVE MYSQL SERVERS TO DISK;
Query OK, 0 rows affected (0.20 sec)mysql> LOAD MYSQL USERS TO RUNTIME;
Query OK, 0 rows affected (0.10 sec)mysql> SAVE MYSQL USERS TO DISK;
Query OK, 0 rows affected (0.05 sec)mysql> LOAD MYSQL QUERY RULES TO RUNTIME;
Query OK, 0 rows affected (0.00 sec)mysql> SAVE MYSQL QUERY RULES TO DISK;
Query OK, 0 rows affected (0.17 sec)
2.1.2 查看组配置表

ProxySQL配置MGR在表mysql_group_replication_hostgroups中

mysql> insert into mysql_group_replication_hostgroups values(1,2,3,4,1,1,0,100,NULL);
Query OK, 1 row affected (0.11 sec)mysql> select * from mysql_group_replication_hostgroups;
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
| writer_hostgroup | backup_writer_hostgroup | reader_hostgroup | offline_hostgroup | active | max_writers | writer_is_also_reader | max_transactions_behind | comment |
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
| 1                | 2                       | 3                | 4                 | 1      | 1           | 0                     | 100                     | NULL    |
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
1 row in set (0.00 sec)
  • write_hostgroup:默认情况下会将所有流量发送到这个组。具有read_only=0的节点也将分配到这个组;
  • backup_writer_hostgroup:如果集群有多个写节点(read_only=0)且超过了max_writers规定数量,则会把多出来的写节点放到备用写组里面;
  • reader_hostgroup:读取的流量应该发送到该组,只读节点(read_only=1)会被分配到该组;
  • offline_hostgroup:当ProxySQL监视到某个节点不正常时,会被放入该组;
  • active:是否启用主机组,当启用时,ProxySQL将监视主机在各族之间移动;
  • max_writers:最大写节点的数量,超过该值的节点应该被放入backup_write_hostgroup;
  • writer_is_also_reader:一个节点既做写节点也做读节点,如果该值为2,则backup_writer_hostgroup的节点做读写点,但是writer_hostgroup不会做读节点;
2.1.3 创建MGR节点状态的函数和视图

在tango-centos01节点上,创建系统视图sys.gr_member_routing_candidate_status,该视图将为ProxySQL提供组复制相关的监控状态指标。

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
BEGINDECLARE 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 DOSET 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 THENSET 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;ELSESET 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
BEGINRETURN (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
BEGINRETURN (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 ;

导入addition_to_sys.sql文件数据

[root@tango-centos01 mysql]# ./bin/mysql -uroot -ppassword < /root/addition_to_sys.sql 
mysql: [Warning] Using a password on the command line interface can be insecure.

在三个mysql节点上可以查看该视图:

[root@tango-centos01 mysql]# ./bin/mysql -uroot –ppassword
............
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.11 sec)

然后授权给监控用户,这一步需要放到2.3.1后执行。

2.1.4 添加MySQL服务器

mysql_server表是用来存储ProxySQL路由转换的MySQL节点的信息。

mysql> insert into mysql_servers (hostgroup_id, hostname, port) values(1,'192.168.112.101',3306);
Query OK, 1 row affected (0.71 sec)mysql> insert into mysql_servers (hostgroup_id, hostname, port) values(1,'192.168.112.102',3306);
Query OK, 1 row affected (0.00 sec)mysql> insert into mysql_servers (hostgroup_id, hostname, port) values(1,'192.168.112.103',3306);
Query OK, 1 row affected (0.00 sec)mysql> select * from mysql_servers;
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname        | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 1            | 192.168.112.101 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 192.168.112.102 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 192.168.112.103 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
3 rows in set (0.02 sec)

然后执行以下命令生效:

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
2.2 配置监控

配置监控信息,用来监控ProxySQL与后端的MySQL通信是否正常

2.2.1 监控用户配置

在ProxySQL的变量表里面设定监控用户密码,用于ProxySQL监控后端MySQL服务器的用户信息

mysql> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
Query OK, 1 row affected (0.20 sec)mysql> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_password';
Query OK, 1 row affected (0.00 sec)mysql> select variable_name,variable_value from global_variables where variable_name in ('mysql-monitor_username','mysql-monitor_password');
+------------------------+----------------+
| variable_name          | variable_value |
+------------------------+----------------+
| mysql-monitor_password | monitor        |
| mysql-monitor_username | monitor        |
+------------------------+----------------+
2 rows in set (0.01 sec)

后台MySQL数据库也需要创建该用户并授权,monitor用户需要有usage权限去连接、ping和检查read_only信息,如果要检测复制延迟,还需要具有replication client权限。在MySQL服务器上创建监控用户:

mysql> create user monitor@'%' identified by 'monitor';
Query OK, 0 rows affected (0.30 sec)mysql> grant usage,replication client on *.* to monitor@'%';
Query OK, 0 rows affected (0.10 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.04 sec)

注意:因为ProxySQL+组复制添加了新的视图,因此还需授权:

mysql> grant select on sys.* to monitor;
Query OK, 0 rows affected (0.01 sec)
2.2.2 配置监控时间间隔

把连接、ping、read_only监控间隔改为5s,默认分别为60s、10s和1.5s

mysql> select * from global_variables where variable_name like 'mysql-monitor%';
+--------------------------------------------------------------+----------------+
| variable_name                                                | variable_value |
+--------------------------------------------------------------+----------------+
| mysql-monitor_enabled                                        | true           |
| mysql-monitor_connect_interval                               | 60000          |
| mysql-monitor_ping_interval                                  | 10000          |
| mysql-monitor_read_only_interval                             | 1500           |
+--------------------------------------------------------------+----------------+
31 rows in set (0.05 sec)mysql> update global_variables set variable_value='5000' where variable_name in('mysql-monitor_connect_interval','mysql-monitor_ping_interval','mysql-monitor_read_only_interval');
Query OK, 3 rows affected (0.00 sec)mysql> select * from global_variables where variable_name like 'mysql-monitor%';                                                                                           +--------------------------------------------------------------+----------------+
| variable_name                                                | variable_value |
+--------------------------------------------------------------+----------------+
| mysql-monitor_connect_interval                               | 5000           |
| mysql-monitor_ping_interval                                  | 5000           |
| mysql-monitor_read_only_interval                             | 5000           |

在修改完变量之后,一定要加载到内存中生效以及永久保存到磁盘中:

LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
2.2.3 检查监控信息

监控配置完成后,我们需要检查ProxySQL与后端MySQL通信是否有异常,monitor数据库中的表用于存储监视信息。

mysql> show tables from monitor;
+--------------------------------------+
| tables                               |
+--------------------------------------+
| mysql_server_aws_aurora_check_status |
| mysql_server_aws_aurora_failovers    |
| mysql_server_aws_aurora_log          |
| mysql_server_connect_log             |
| mysql_server_galera_log              |
| mysql_server_group_replication_log   |
| mysql_server_ping_log                |
| mysql_server_read_only_log           |
| mysql_server_replication_lag_log     |
+--------------------------------------+
9 rows in set (0.06 sec)

1)查看ProxySQL与后台服务器连接是否正常:

mysql> select * from monitor.mysql_server_connect_log order by time_start_us desc limit 10;
+-----------------+------+------------------+-------------------------+---------------+
| hostname        | port | time_start_us    | connect_success_time_us | connect_error |
+-----------------+------+------------------+-------------------------+---------------+
| 192.168.112.102 | 3306 | 1626010060482799 | 7885                    | NULL          |
| 192.168.112.101 | 3306 | 1626010060435070 | 7818                    | NULL          |
| 192.168.112.103 | 3306 | 1626010060392373 | 8380                    | NULL          |
| 192.168.112.101 | 3306 | 1626010055527941 | 7887                    | NULL          |
| 192.168.112.103 | 3306 | 1626010055461763 | 13077                   | NULL          |
| 192.168.112.102 | 3306 | 1626010055392170 | 21548                   | NULL          |
| 192.168.112.103 | 3306 | 1626010050459140 | 8479                    | NULL          |
| 192.168.112.101 | 3306 | 1626010050424961 | 7825                    | NULL          |
| 192.168.112.102 | 3306 | 1626010050390742 | 7847                    | NULL          |
| 192.168.112.103 | 3306 | 1626010045524843 | 7054                    | NULL          |
+-----------------+------+------------------+-------------------------+---------------+
10 rows in set (0.00 sec)

2)查看组复制是否正常,检查节点是否只读和交易滞后时间:

mysql> select * from mysql_server_group_replication_log order by time_start_us desc limit 10;
+-----------------+------+------------------+-----------------+------------------+-----------+---------------------+-------+
| hostname        | port | time_start_us    | success_time_us | viable_candidate | read_only | transactions_behind | error |
+-----------------+------+------------------+-----------------+------------------+-----------+---------------------+-------+
| 192.168.112.103 | 3306 | 1626011487030240 | 5312            | YES              | NO        | 0                   | NULL  |
| 192.168.112.102 | 3306 | 1626011487025966 | 4132            | YES              | NO        | 0                   | NULL  |
| 192.168.112.101 | 3306 | 1626011487021645 | 4430            | YES              | NO        | 0                   | NULL  |
| 192.168.112.103 | 3306 | 1626011482040056 | 11171           | YES              | NO        | 0                   | NULL  |
| 192.168.112.102 | 3306 | 1626011482029605 | 10298           | YES              | NO        | 0                   | NULL  |
| 192.168.112.101 | 3306 | 1626011482019074 | 10640           | YES              | NO        | 0                   | NULL  |
| 192.168.112.103 | 3306 | 1626011477022158 | 5085            | YES              | NO        | 0                   | NULL  |
| 192.168.112.102 | 3306 | 1626011477018017 | 4609            | YES              | NO        | 0                   | NULL  |
| 192.168.112.101 | 3306 | 1626011477012678 | 5124            | YES              | NO        | 0                   | NULL  |
| 192.168.112.103 | 3306 | 1626011472020643 | 5232            | YES              | NO        | 0                   | NULL  |
+-----------------+------+------------------+-----------------+------------------+-----------+---------------------+-------+
10 rows in set (0.03 sec)

3)查看ProxySQL ping后端MySQL服务器是否正常:

mysql> select * from mysql_server_ping_log order by time_start_us desc limit 10;
+-----------------+------+------------------+----------------------+------------+
| hostname        | port | time_start_us    | ping_success_time_us | ping_error |
+-----------------+------+------------------+----------------------+------------+
| 192.168.112.102 | 3306 | 1626010155400644 | 4326                 | NULL       |
| 192.168.112.103 | 3306 | 1626010155352647 | 4347                 | NULL       |
| 192.168.112.101 | 3306 | 1626010155304706 | 2967                 | NULL       |
| 192.168.112.103 | 3306 | 1626010150390731 | 7044                 | NULL       |
| 192.168.112.101 | 3306 | 1626010150347020 | 2168                 | NULL       |
| 192.168.112.102 | 3306 | 1626010150303801 | 707                  | NULL       |
| 192.168.112.102 | 3306 | 1626010145401849 | 3872                 | NULL       |
| 192.168.112.103 | 3306 | 1626010145350884 | 3883                 | NULL       |
| 192.168.112.101 | 3306 | 1626010145299002 | 3749                 | NULL       |
| 192.168.112.102 | 3306 | 1626010140401854 | 3841                 | NULL       |
+-----------------+------+------------------+----------------------+------------+
10 rows in set (0.00 sec)

通过监控信息,我们可以得出结论,所有配置都是健康的,继续下一步

2.3 用户配置

使用了ProxySQL,则要先使用账号密码访问到ProxySQL的数据库,然后再由ProxySQL进行用户请求的转发,当中间件用户与数据库用户以及密码一致时,才能正常访问数据库。

1)在MySQL数据库上创建用户:proxyuser

mysql> create user `proxyuser`@`%` identified by '123456';
Query OK, 0 rows affected (0.05 sec)mysql> grant all privileges on *.* to `proxyuser`@`%`;
Query OK, 0 rows affected (0.00 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

2)在ProxySQL上创建用户:proxyuser

mysql> insert into mysql_users(username,password,default_hostgroup) values('proxyuser','123456',1);
Query OK, 1 row affected (0.03 sec)mysql> load mysql users to runtime;
Query OK, 0 rows affected (0.00 sec)mysql> save mysql users to disk;
Query OK, 0 rows affected (0.05 sec)
3、故障切换测试
3.1 主节点故障测试

1)查看当前写节点

##查看mysql_server在memory层的配置信息
mysql> select * from mysql_servers;
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname        | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 1            | 192.168.112.101 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 192.168.112.102 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 192.168.112.103 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
3 rows in set (0.00 sec)

加载到RUNTIME后,由于组定义中最多只有1个写节点,其余的主节点移动到备用写组里面,可以看到192.168.112.103为写节点、其余为读节点。

mysql> select * from runtime_mysql_servers;
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname        | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 1            | 192.168.112.103 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 2            | 192.168.112.102 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 2            | 192.168.112.101 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
3 rows in set (0.00 sec)

使用ProxySQL来访问MyQSL集群,发现可以支持读写

##使用ProxySQL 6033端口访问MySQL数据库
[root@tango-01 mysql]# ./bin/mysql -uproxyuser -p123456 -P6033 -h192.168.112.10
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tango              |
+--------------------+
9 rows in set (0.29 sec)mysql> use tango;
mysql> show tables;
+-----------------+
| Tables_in_tango |
+-----------------+
| tb01            |
+-----------------+
1 row in set (0.16 sec)##通过主机名,额可以看到,我们访问到的是写节点
mysql> select @@hostname;
+----------------+
| @@hostname     |
+----------------+
| tango-centos03 |
+----------------+
1 row in set (0.01 sec)##插入、查询数据
mysql> insert into tango.tb01 values(10,'aa');
Query OK, 1 row affected (0.06 sec)mysql> select * from tango.tb01;
+----+------+
| id | name |
+----+------+
| 10 | aa   |
+----+------+
6 rows in set (0.00 sec)

2)关闭写节点

##直接关闭mysql服务
[root@tango-centos03 mysql]# service mysql statusSUCCESS! MySQL running (2164)
[root@tango-centos03 mysql]# service mysql stop
Shutting down MySQL.............. SUCCESS! 
[root@tango-centos03 mysql]# service mysql statusERROR! MySQL is not running##需要注意的是,以前连接在主节点上的会话会断开,不会转移到新的主节点
mysql> select * from tango.tb01;
ERROR 2013 (HY000): Lost connection to MySQL server during query

3)查看是否会有备用写节点转为写节点,可以看到192.168.112.102服务器已经转为写节点,而已经关闭的192.168.112.103服务器状态为SHUNNE,已经进入离线组offline_hostgroup。

mysql> select * from runtime_mysql_servers;
+--------------+-----------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname        | port | gtid_port | status  | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+-----------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 1            | 192.168.112.102 | 3306 | 0         | ONLINE  | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 4            | 192.168.112.103 | 3306 | 0         | SHUNNED | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 2            | 192.168.112.101 | 3306 | 0         | ONLINE  | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+-----------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
3 rows in set (0.00 sec)

4)再次使用ProxySQL来访问MyQSL集群,发现可以支持读写,业务不会因主节点的改变而受影响。

##使用ProxySQL 6033端口访问MySQL数据库
[root@tango-01 mysql]# ./bin/mysql -uproxyuser -p123456 -P6033 -h192.168.112.10
mysql> use tango;##通过主机名,额可以看到,我们访问到的是新的写节点
mysql> select @@hostname;
+----------------+
| @@hostname     |
+----------------+
| tango-centos02 |
+----------------+
1 row in set (0.00 sec)##插入、查询数据
mysql> insert into tango.tb01 values(12,'bb');
Query OK, 1 row affected (0.12 sec)mysql> select * from tango.tb01;
+----+------+
| id | name |
+----+------+
| 10 | aa   |
| 12 | bb   |
+----+------+
7 rows in set (0.01 sec)
3.2 故障影响测试

使用sysbench进行测试,确认主节点故障过程中对业务的影响。

1)安装sysbench

[root@tango-01 ~]# yum install -y sysbench
[root@tango-01 ~]# sysbench --version
sysbench 1.0.17

2)初始化表数据

[root@tango-01 ~]# cd /usr/share/sysbench/
[root@tango-01 sysbench]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.112.102 --mysql-port=3306 --mysql-user=root --mysql-password=password --oltp-test-mode=complex --oltp-tables-count=5 --oltp-table-size=50000 prepare

3)执行测试

##通过proxy连接到数据库
[root@tango-01 sysbench]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.112.10 --mysql-port=6033 --mysql-user=proxyuser --mysql-password=123456 --oltp-test-mode=complex --oltp-tables-count=5 --oltp-table-size=50000 --threads=100 --time=600 --report-interval=1 run

4)测试结果

TPS和QPS排除测试环境资源抖动因素,在正常范围内波动,没有出现TPS或者QPS降为0的情况出现。

在这里插入图片描述
在这里插入图片描述

总结:通过上面的测试,可以看到MGR结合ProxySQL已经可以实现业务的自动故障转移,当主节点出现故障时,业务可以自动切换到其它节点对外服务,这个切换过程对业务基本是无感知的。


参考资料:

  1. https://blog.csdn.net/weixin_30895723/article/details/107739977
  2. https://www.cnblogs.com/kevingrace/p/10384691.html
  3. https://blog.csdn.net/solihawk/article/details/117697624
  4. 数据库系列之MySQL组复制MGR

转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/119560410
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!
在这里插入图片描述

这篇关于数据库系列之MySQL高可用MGR故障自动切换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/622620

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

如何去写一手好SQL

MySQL性能 最大数据量 抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。 博主曾经操作过超过4亿行数据

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言