云原生高级-MySQL集群
一、MySQL集群核心理论
1 核心定义
MySQL集群(MySQL Cluster)是由MySQL AB公司(后被Oracle收购)开发的分布式数据库解决方案,核心是将MySQL数据库的存储、计算、连接等功能拆分到多个节点,通过节点间的协同工作,实现数据的高可用、高并发、可扩展,同时保证数据的一致性和可靠性。
本质:基于分布式架构,将数据分片存储在多个节点,节点间通过专用通信协议同步数据、协调任务,对外提供统一的数据库访问入口,屏蔽底层节点的分布式细节,让用户像使用单节点MySQL一样操作集群。
核心前提:集群中所有节点需处于同一网络环境(通常是局域网),节点间通信延迟低、稳定性高,避免因网络问题导致数据同步异常或集群故障。
2 核心价值(为什么要用集群)
2.1 高可用性(High Availability)
核心目标:避免单点故障,确保数据库服务持续可用。单节点MySQL一旦出现硬件故障、软件崩溃、网络中断等问题,服务会完全中断;而集群通过多节点冗余部署,当某一个或多个节点故障时,其他正常节点可立即接管服务,实现“无停机”或“秒级停机”切换,保障业务连续运行。
关键指标:可用性达到99.99%以上(每年停机时间不超过52分钟),核心场景(如电商、金融)可通过多副本部署进一步提升可用性。
2.2 高并发处理能力(High Concurrency)
单节点MySQL的并发连接数、QPS(每秒查询数)存在上限(受CPU、内存、IO等硬件限制),当业务并发量突破单节点瓶颈时,会出现查询延迟、连接超时等问题。
集群通过“负载均衡”将并发请求分发到多个节点,每个节点承担部分请求压力,从而整体提升集群的并发处理能力,支持 thousands 级甚至 tens of thousands 级的并发连接。
2.3 可扩展性(Scalability)
业务增长过程中,数据量会持续增加(如从GB级增长到TB级、PB级),单节点的存储和计算能力无法满足需求。MySQL集群支持“横向扩展”(增加节点数量),无需停机,即可扩展存储容量和计算能力,适配业务的动态增长。
对比:单节点只能“纵向扩展”(升级CPU、内存、硬盘),扩展成本高、上限低,且升级过程中需停机,影响业务。
2.4 数据可靠性(Data Reliability)
集群通过“数据副本”机制,将同一份数据存储在多个节点(通常是2-3个副本),当某一个节点的数据损坏或丢失时,可从其他副本节点恢复数据,避免数据丢失。同时,数据同步过程会进行校验,确保副本数据与主数据一致。
3 核心架构分类(主流类型)
MySQL集群的架构核心是“节点角色拆分”,不同角色的节点承担不同的功能,主流架构分为三类,其中主从复制架构最常用,Galera Cluster和NDB Cluster适用于特定场景。
3.1 主从复制架构(Master-Slave Replication)
(1)架构组成
- 主节点(Master):唯一的写节点,负责接收所有写请求(INSERT、UPDATE、DELETE),并将写操作记录到二进制日志(binlog)。
- 从节点(Slave):只读节点(可配置为读写,但不推荐),通过IO线程读取主节点的binlog,通过SQL线程将binlog中的操作在本地重放,实现与主节点的数据同步。
- 可选组件:中继日志(relay log),从节点接收的binlog先存储到中继日志,再由SQL线程读取重放,避免直接操作主节点binlog,提升稳定性。
(2)核心原理
- 主节点开启binlog,每执行一次写操作,就将操作记录到binlog中(按时间顺序记录,不可篡改)。
- 从节点启动IO线程,与主节点建立连接,请求主节点发送binlog(从指定的位置开始读取)。
- 主节点启动binlog dump线程,将binlog内容逐段发送给从节点的IO线程。
- 从节点的IO线程将接收的binlog写入本地中继日志,SQL线程读取中继日志,将其中的操作逐行执行,实现主从数据同步。
(3)特点
- 优点:架构简单、部署成本低、易维护,适合读多写少的场景(如博客、新闻网站),可通过增加从节点提升读并发。
- 缺点:存在主从延迟(binlog同步需要时间,通常是毫秒级,极端情况可达秒级),主节点是单点故障(主节点故障后,需手动切换到从节点),写并发受主节点限制。
3.2 Galera Cluster(同步多主集群)
(1)架构组成
所有节点都是主节点(Multi-Master),无主从之分,每个节点都可接收写请求,节点间通过Galera协议实现数据同步,确保所有节点的数据一致。
核心组件:Galera插件(需安装在每个MySQL节点上),负责节点间的通信、数据同步和一致性校验。
(2)核心原理
采用“同步复制”机制,当某一个节点执行写操作时,会先将操作发送给集群中所有其他节点,待所有节点确认执行成功后,再向客户端返回“操作成功”,确保所有节点的数据实时一致,无主从延迟。
容错机制:集群中最多允许(节点数-1)/2个节点故障,剩余节点仍可正常提供服务(如3个节点可允许1个故障,5个节点可允许2个故障)。
(3)特点
- 优点:无主从延迟、支持多节点写并发,故障自动切换(无需手动干预),可用性高,适合写多读少、对数据一致性要求高的场景(如金融交易、电商订单)。
- 缺点:部署复杂、成本高,写操作性能略低(需等待所有节点确认),节点数量不宜过多(通常3-5个节点)。
3.3 NDB Cluster(内存集群)
(1)架构组成
- 管理节点(Management Node):负责集群的配置、监控和节点管理,是集群的“大脑”,不存储数据、不处理请求。
- 数据节点(Data Node):负责存储数据,数据存储在内存中(可配置持久化到磁盘),支持数据分片,多个数据节点共同承担存储压力。
- SQL节点(SQL Node):负责接收客户端的SQL请求,解析SQL并分发到数据节点执行,返回结果给客户端,相当于“查询入口”。
(2)核心原理
数据分片:将表中的数据按指定规则(如哈希、范围)拆分到多个数据节点,每个数据节点存储部分数据,提升存储和查询效率;数据副本:每个数据分片会存储多个副本(通常2个),确保数据可靠性;所有操作通过管理节点协调,数据节点间通过专用协议同步数据。
(3)特点
- 优点:读写性能极高(数据在内存中),支持海量数据分片存储,高可用、高容错,适合对性能要求极高、数据量极大的场景(如游戏、日志分析)。
- 缺点:部署复杂、内存成本高,不适合大量写操作(内存写入虽快,但同步成本高),对SQL语法有一定限制。
4 关键技术
4.1 数据分片(Sharding)
定义:将数据库中的大表,按指定规则(分片键)拆分成多个小表,每个小表存储在不同的节点上,实现数据的分布式存储。
核心目的:解决单节点存储容量不足、查询效率低的问题,提升集群的存储和查询性能。
常见分片方式:
- 哈希分片:以分片键(如用户ID)的哈希值为依据,将数据均匀分配到多个节点,优点是数据分布均匀,缺点是无法范围查询(如查询ID在1-1000的用户)。
- 范围分片:以分片键的范围为依据(如时间、ID范围),将数据分配到不同节点,优点是支持范围查询,缺点是数据可能分布不均(如某一时间段数据量过大)。
- 列表分片:按分片键的具体值列表分配数据(如按地区分片:北京、上海的数据存节点A,广州、深圳的数据存节点B),适合有明确分类的场景。
4.2 数据复制(Replication)
定义:将一个节点(主节点)的数据,复制到其他节点(从节点/副本节点),确保多个节点的数据一致,是实现高可用、数据可靠性的核心技术。
常见复制类型:
- 异步复制(默认,主从复制常用):主节点执行写操作后,立即向客户端返回成功,同时异步将binlog发送给从节点,从节点异步重放。优点是写性能高,缺点是存在主从延迟,主节点故障可能导致数据丢失。
- 半同步复制(主从复制优化):主节点执行写操作后,需等待至少一个从节点确认接收binlog后,再向客户端返回成功。优点是减少数据丢失风险,缺点是写性能略有下降。
- 同步复制(Galera Cluster常用):主节点执行写操作后,需等待所有副本节点确认执行成功后,再返回客户端。优点是数据实时一致,无延迟,缺点是写性能较低。
4.3 负载均衡(Load Balancing)
定义:将客户端的请求,根据节点的负载情况(CPU、内存、IO使用率、连接数),合理分发到多个节点,避免单个节点过载,提升集群的整体并发处理能力。
常见实现方式:
- 硬件负载均衡:通过专用硬件设备(如F5、NetScaler)分发请求,性能高、稳定性强,适合大型集群,成本高。
- 软件负载均衡:通过软件(如Nginx、HAProxy)分发请求,成本低、配置灵活,适合中小型集群,性能略低于硬件负载均衡。
- MySQL自带负载均衡:如Galera Cluster的内置负载均衡,可自动分发请求到不同节点,无需额外部署软件/硬件。
4.4 故障检测与自动切换(Failover)
核心目的:当集群中的节点出现故障时,自动检测故障节点,将故障节点的任务切换到正常节点,确保服务不中断,是实现高可用的关键。
核心流程:
- 故障检测:通过节点间的心跳机制(定期发送检测包),判断节点是否正常(如心跳中断超过阈值,判定为节点故障)。
- 故障隔离:将故障节点从集群中隔离,避免其影响集群正常运行(如停止向故障节点分发请求)。
- 任务切换:将故障节点的任务(如主节点的写任务、从节点的读任务)切换到正常节点(如主从复制中,将从节点提升为主节点)。
- 恢复同步:故障节点修复后,重新加入集群,同步缺失的数据,恢复正常服务。
常见工具:MHA(Master High Availability,主从复制架构的自动切换工具)、Galera Cluster内置自动切换功能。
5 核心特性与限制
5.1 核心特性
- 透明性:对外提供统一的数据库访问入口,用户无需关心底层节点的分布和操作,像使用单节点MySQL一样操作集群。
- 一致性:通过数据复制、校验机制,确保集群中所有节点的数据一致(不同架构的一致性级别不同,如Galera是强一致性,主从复制是最终一致性)。
- 容错性:支持节点故障,故障节点修复后可自动重新加入集群,不影响整体服务。
- 可管理性:通过管理工具(如MySQL Cluster Manager、MHA),可实现集群的配置、监控、运维、故障排查。
5.2 主要限制
- 复杂度高:集群部署、配置、运维难度远高于单节点MySQL,需要专业的运维人员。
- 成本高:需要多个服务器节点,硬件、网络成本增加;同时,运维成本也更高。
- 性能损耗:节点间的数据同步、请求分发会产生一定的性能损耗(如同步复制的写性能损耗)。
- 语法限制:部分MySQL语法在集群中不支持(如NDB Cluster不支持外键、存储过程),需适配集群架构。
6 适用场景与选型建议
6.1 适用场景
- 读多写少,并发量高:如博客、新闻、电商商品列表,适合主从复制架构(主节点写,多从节点读)。
- 写多读少,数据一致性要求高:如金融交易、电商订单、支付系统,适合Galera Cluster(同步多主,无延迟)。
- 数据量大,性能要求极高:如游戏日志、用户行为分析,适合NDB Cluster(内存存储,分片部署)。
- 业务连续性要求高:如核心业务系统,需避免单点故障,适合任何一种集群架构(优先Galera Cluster)。
6.2 选型建议
- 中小型业务、读多写少、预算有限:优先选择主从复制架构(部署简单、成本低)。
- 中大型业务、写并发高、数据一致性要求高:选择Galera Cluster(多主同步、自动故障切换)。
- 海量数据、高并发读写、性能要求极高:选择NDB Cluster(内存存储、分片扩展)。
- 核心业务、无停机需求:建议搭配负载均衡工具和自动切换工具,提升集群可用性。
7 核心总结
- MySQL集群的核心目标是解决单节点的单点故障、并发瓶颈、存储限制,实现高可用、高并发、可扩展。
- 三大主流架构各有侧重:主从复制(简单、低成本,读多写少)、Galera Cluster(同步多主、高一致,写多读少)、NDB Cluster(内存、高性能,海量数据)。
- 关键技术支撑:数据分片(扩展存储)、数据复制(保证一致)、负载均衡(提升并发)、故障切换(保证可用)。
- 选型核心:结合业务的读写比例、数据量、性能要求、预算,选择合适的架构,避免过度设计。
二、 MySQL 集群基础与进阶实验
1 Mysql的源码编译
1.1 下载安装包
1 | wget https://downloads.mysql.com/archives/get/p/23/file/mysql-boost-8.3.0.tar.gz |
1.2 源码编译
1 | [root@mysql ~]# dnf install cmake3 gcc git bison openssl-devel ncurses-devel systemd-devel rpcgen.x86_64 libtirpc-devel-1.3.3-9.el9.x86_64.rpm gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils gcc-toolset-12-annobin-annocheck gcc-toolset-12-annobin-plugin-gcc -y |
1.3 部署
1 | [root@mysql build]# make install |
1.4 数据结构初始化
1 | [root@mysql ~]# mysqld --initialize --user=mysql |
1.5 启动
1 | [root@mysql ~]# dnf install initscripts-10.11.8-4.el9.x86_64 -y |
1.6 安全初始化
1 | [root@mysql ~]# mysql_secure_installation |
1.7 从机部署MySQL
(1)从主机发送编译好的MySQL
1 | scp -rp /usr/local/mysql root@:172.25.254.130/usr/local |
(2)后续同主机[部署](#1.3 部署)
2 MySQ集群实验
2.1 主从复制(库内无数据)
(1)编写主配置文件(my.cnf)
1 | # Master |
(2)建立数据库账号
- master
1 | [root@mysql-node1 ~]# mysql -uroot -ppasswd |
- slave1 or 2
1 | [root@MySQL2 ~]# mysql -uhua -phua -h172.25.254.129 |
(3)配置数据库一主一从
- master
1 | #查看日志文件名称及id |
- slave
1 | [root@mysql-node2 ~]# mysql -uroot -ppasswd |
RESET REPLICA ALL; 重置副本(从机)
RESET MASTER ALL; 重置副本(主机)
(4)测试
- master
1 | [root@mysql ~]# mysql -uroot -ppasswd |
- slave
1 | [root@MySQL2 ~]# mysql -uroot -ppasswd |
2.2 主从复制(库内有数据)
(1)向当前一主一从中加入新的数据库
1 | #模拟一主一从中已经存在数据情况 |
(2)将新库加入主从结构中
1 | #在master中查看日志的id |
1 | [root@MySQL3 ~]# mysql -uroot -ppasswd |
(3)测试
1 | #在master中建立数据 |
3 MySQL集群优化
3.1 延迟复制
slave
1
2
3
4
5
6
7#安装数据库的版本 >= 8.0
[root@MySQL2 ~]# mysql -uroot -ppasswd
mysql> STOP REPLICA;
mysql> CHANGE REPLICATION SOURCE TO SOURCE_DELAY=60;
mysql> START REPLICA;
mysql> SHOW REPLICA STATUS\G
SQL_Delay: 60 # 延迟时间1minmaster
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[root@MySQL ~]# mysql -uroot -ppasswd
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
mysql> delete from test.userlist where name='user1';
mysql> select * from test.userlist;
+-------+------+
| name | pass |
+-------+------+
| user2 | 123 |
+-------+------+slave
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#在未被延迟的slave数据库中查看是否数据操作动作被同步
mysql> select * from timinglee.userlist;
+-------+------+
| name | pass |
+-------+------+
| user2 | 123 |
+-------+------+
#在被设定延迟复制的主机中查看动作是否被同步
mysql> select * from timinglee.userlist;
+-------+------+
| name | pass |
+-------+------+
| user1 | 123 |
| user2 | 123 |
+-------+------+
#等待延迟时间过后再次查看
mysql> select * from timinglee.userlist;
+-------+------+
| name | pass |
+-------+------+
| user2 | 123 |
+-------+------+
3.2 慢查询日志
master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71#慢查询日志是否开启
mysql> SHOW variables like "slow%";
+---------------------+----------------------------+
| Variable_name | Value |
+---------------------+----------------------------+
| slow_launch_time | 2 |
| slow_query_log | OFF |
| slow_query_log_file | /data/mysql/mysql-slow.log |
+---------------------+----------------------------+
#开启慢查询日志
mysql> SET GLOBAL slow_query_log=ON;
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW variables like "slow%";
+---------------------+----------------------------+
| Variable_name | Value |
+---------------------+----------------------------+
| slow_launch_time | 2 |
| slow_query_log | ON |
| slow_query_log_file | /data/mysql/mysql-slow.log |
+---------------------+----------------------------+
3 rows in set (0.00 sec)
#检测慢查询日志
mysql> SHOW VARIABLES like "long%"; #慢查询阈值
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.01 sec)
mysql> SET long_query_time=4;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES like "long%";
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 4.000000 |
+-----------------+----------+
1 row in set (0.00 sec)
mysql> select sleep (3); #不会生成慢查询日志
+-----------+
| sleep (3) |
+-----------+
| 0 |
+-----------+
1 row in set (3.00 sec)
mysql> select sleep (4);
+-----------+
| sleep (4) |
+-----------+
| 0 |
+-----------+
1 row in set (4.00 sec)
[root@MySQL ~]# cat /data/mysql/mysql-slow.log
/usr/local/mysql/bin/mysqld, Version: 8.3.0 (Source distribution). started with:
Tcp port: 3306 Unix socket: /data/mysql/mysql.sock
Time Id Command Argument
# Time: 2026-02-27T02:30:07.869255Z
# User@Host: root[root] @ localhost [] Id: 12
# Query_time: 4.001001 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1
SET timestamp=1772159403;
select sleep (4);
3.3 gtid模式
在master和slave中默认gtid模式是未开启的
1 | show variables like '%gtid%'; |

master + slave
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22[root@MySQL1~3 ~]# vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=ON
[root@MySQL1~3 ~]# /etc/init.d/mysqld restart
#在三台主机中分别查看gtid模式是否开启
mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | |
| gtid_executed_compression_period | 0 |
| gtid_mode | ON |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
9 rows in set (0.00 sec)slave
1
2
3
4
5
6
7#在从库中停止slave功能;
mysql> STOP REPLICA;
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.129', MASTER_USER='hua', MASTER_PASSWORD='hua', MASTER_AUTO_POSITION=1;
mysql> START REPLICA;
mysql> SHOW REPLICA STATUS \G;
3.4 多线程回放
slave
1
2#在slave主机中默认回方日志时使用单线程回放
mysql> show processlist;1
2
3
4
5
6
7
8
9
10#开启多线程回放日志
[root@MySQL2 ~]# vim /etc/my.cnf
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16
relay_log_recovery=ON
[root@MySQL2 ~]# /etc/init.d/mysqld restart
#查看更改生效信息
mysql> show processlist;
3.5 半同步模式
master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#在master主机中操作
[root@mysql-node1~3 ~]# vim /etc/my.cnf
rpl_semi_sync_master_enabled=1 # 启用半同步复制
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; # 安装半同步复制的主库插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%'; #验证安装
+----------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE |
+----------------------+---------------+
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON | # 主库半同步开关是否开启(ON=开启,OFF=关闭)
| rpl_semi_sync_master_timeout | 10000 | # 主库等待从库确认的超时时间(单位:毫秒,默认10秒)
| rpl_semi_sync_master_trace_level | 32 | # 调试跟踪级别(默认值,无需修改)
| rpl_semi_sync_master_wait_for_slave_count | 1 | # 主库需要等待至少多少个从库确认(默认1个)
| rpl_semi_sync_master_wait_no_slave | ON | # 无可用从库时,是否等待后降级为异步(ON=是)
| rpl_semi_sync_master_wait_point | AFTER_SYNC | # 主库等待时机(AFTER_SYNC=写binlog后等,更安全)
+-------------------------------------------+------------+
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 | # 已连接的半同步从库数量(至少1个才会走半同步)
| Rpl_semi_sync_master_net_avg_wait_time | 0 | # 等待从库确认的平均网络时间
| Rpl_semi_sync_master_net_wait_time | 0 | # 累计等待从库确认的网络时间
| Rpl_semi_sync_master_net_waits | 0 | # 累计等待从库确认的次数
| Rpl_semi_sync_master_no_times | 0 | # 降级为异步的次数(超时/无从库)
| Rpl_semi_sync_master_no_tx | 0 | # 未走半同步的事务数
| Rpl_semi_sync_master_status | ON | # 当前主库是否处于半同步模式(核心字段)
| Rpl_semi_sync_master_timefunc_failures | 0 | # 时间函数失败次数(异常排查用)
| Rpl_semi_sync_master_tx_avg_wait_time | 0 | # 事务等待从库确认的平均时间
| Rpl_semi_sync_master_tx_wait_time | 0 | # 累计事务等待时间
| Rpl_semi_sync_master_tx_waits | 0 | # 累计事务等待次数
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 | # 等待位置回退次数
| Rpl_semi_sync_master_wait_sessions | 0 | # 正在等待从库确认的会话数
| Rpl_semi_sync_master_yes_tx | 0 | # 成功走半同步的事务数
+--------------------------------------------+-------+slave
1
2
3
4
5
6
7
8
9
10
11
12
13
14[root@MySQL2+3 ~]# vim /etc/my.cnf
rpl_semi_sync_slave_enabled=1
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;
mysql> STOP SLAVE IO_THREAD;
mysql> START SLAVE IO_THREAD;
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'rpl_semi_sync_slave';
+---------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+---------------------+---------------+
| rpl_semi_sync_slave | ACTIVE |
+---------------------+---------------+测试
master
1
2
3
4mysql> create database test2;
Query OK, 1 row affected (10.01 sec) #有等待ack时间
mysql> INSERT INTO test.userlist values ('user3','123'); # 写入数据slave
1
mysql> STOP SLAVE IO_THREAD; #模拟ack故障
master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# 查看效果
mysql> INSERT INTO test.userlist values ('user3','123');
Query OK, 1 row affected (10.01 sec) # ack故障时间
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 4 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 570 |
| Rpl_semi_sync_master_tx_wait_time | 1712 |
| Rpl_semi_sync_master_tx_waits | 3 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 3 |
+--------------------------------------------+-------+slave
1
2#恢复故障
mysql> START SLAVE IO_THREAD;
4 MySQL高可用
4.1 MHA
(1) 配置Mha-manager
1 | [root@MHA ~]# unzip MHA-7.zip |
在slave中安装相应软件
1 | [root@MHA MHA-7]# for i in 129 130 131 |
修改MHA-Manager中的检测代码
1 | [root@mha MHA-7]# vim /usr/share/perl5/vendor_perl/MHA/NodeUtil.pm |
未MHA建立远程登录用户
1 | #在master主机中 |
生成MHA-manager的配置文件模板
1 | [root@mha MHA-7]# tar zxf mha4mysql-manager-0.58.tar.gz |
修改配置文件
1 | user=root |
检测环境
1 | masterha_check_ssh --conf=/etc/masterha/app1.cnf |
特:
1 | ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'passwd'; |
4.2 MGA
I. 通过Ansible控制子节点实现还原
ansible安装与配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 配置仓库
[root@MHA ~]# cat > /etc/yum.repos.d/epel.repo <<EOF
> [epel]
> name = epel
> baseurl = https://mirrors.aliyun.com/epel-archive/9.6/Everything/x86_64/
> gpgcheck = 0
> EOF
# 安装软件包
[root@MHA ~]# dnf install ansible -y
# 验证安装
[root@MHA ~]# ansible --version
ansible [core 2.14.18]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.9/site-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.9.21 (main, Feb 10 2025, 00:00:00) [GCC 11.5.0 20240719 (Red Hat 11.5.0-5)] (/usr/bin/python3)
jinja version = 3.1.2
libyaml = True创建普通用户与密码,保障权限安全问题
1
2
3
4
5[root@MHA ~]# useradd devops
[root@MHA ~]# echo hua | passwd --stdin devops
更改用户 devops 的密码 。
[root@MHA ~]# su - devops
[devops@MHA ~]$ mkdir ansible创建配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[devops@MHA ansible]$ vim inventory
[mysql]
172.25.254.129
172.25.254.130
172.25.254.131
[devops@MHA ansible]$ cat >ansible.cfg <<EOF
> [defaults]
> inventory=./inventory
> remote_user=root
> host_key_checking=false
> [privilege_escalation]
> become=False
> EOF通过主节点控制子节点
1
2
3
4
5
6
7
8
9
10# 创建 devops 用户
ansible mysql -m user -a 'name=devops'
# 设置 devops 用户密码
ansible mysql -m shell -a 'echo devops | passwd --stdin devops'
# 配置 devops 用户免密 sudo 权限
ansible mysql -m shell -a 'echo "devops ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers'
# 创建 devops 用户的 .ssh 目录并设置权限
ansible all -m file -a 'path=/home/devops/.ssh owner=devops group=devops mode="0700" state=directory'
# 复制 SSH 公钥到 devops 用户的 authorized_keys 文件
ansible all -m copy -a 'src=/home/devops/.ssh/authorized_keys dest=/home/devops/.ssh/authorized_keys owner=devops group=devops mode="0600"'配置免密
1
2
3
4
5
6
7
8
9
10
11
12[devops@MHA ansible]$ cat >ansible.cfg <<EOF
> [defaults]
> inventory=./inventory
> remote_user=devops
> host_key_checking=false
>
> [privilege_escalation]
> become=True
> become_ask_pass=False
> become_method=sudo
> become_user=root
> EOF验证
1
2
3
4
5
6
7[devops@mha ansible]$ ansible all -m shell -a 'whoami'
172.25.254.20 | CHANGED | rc=0 >>
root
172.25.254.30 | CHANGED | rc=0 >>
root
172.25.254.10 | CHANGED | rc=0 >>
root编辑自动部署配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25[devops@mha ansible]$ vim clear_mysql.yml
- name: 重 新 部 署 MySQL
hosts: mysql
tasks:
- name: 停 止 MySQL
shell: '/etc/init.d/mysqld stop'
ignore_errors: yes
- name: 删 除 MySQL 数 据
file:
path: /data/mysql
state: absent
- name: 创 建 MySQL 数 据 文 件
file:
path: /data/mysql
state: directory
owner: mysql
group: mysql
- name: 初 始 化 MySQL
shell: '/usr/local/mysql/bin/mysqld --initialize --user=mysql'
[devops@mha ansible]$ ansible-playbook clear_mysql.yml -vv | grep password
II. 手动还原方式
1 | #所有节点初始化数据 |
III. 部署组复制
1 | #设置所有mysql节点的解析 |














