MySQL集群高可用工具Xenon
目录
1、xenon基础介绍
1.1. xenon是什么
Xenon是一款由青云开发团队开源的新一代 MySQL集群高可用工具。基于 Raft协议进行无中心化选主,实现主从秒级切换;基于Semi-Sync机制,保障数据不丢失,实现数据强一致性。并结合MySQL(5.7及以上版本)并行复制特性,实现Binlog并行回放,大大降低从库延迟。
xenon的github地址为:https://github.com/radondb/xenon
1.2. xenon的架构
Xenon的特点
(1)、Xenon基于Raft协议进行无中心化选主,并能实现秒级切换。
(2)、数据一致性依赖于无损半同步Semi-Sync。
(3)、借助于配置项leader-start-command和leader-stop-command调用脚本完成故障切换,同时,通过调用Xtrabackup可实现数据备份和恢复。
(4)、支持MySQL5.6、5.7、8.0内核版本。

1.3. Xenon的工作原理
Xenon是基于Raft+Semi-Sync+GTID实现的高可用, 保证大多数节点接收到数据。而Raft基于心跳管理, 如果从节点超时收不到主的心跳, 会尝试发起选举, 若得到超过半数(非 IDLE 节点)的选票, 则会当选为主节点。
下面以三节点 (一主两从) Xenon集群来简单说明工作原理。
{Leader, [GTID:{1,2,3,4,5}]}
{Follower1, [GTID:{1,2,3,4,5}]}
{Follower2, [GTID:{1,2,3}]}
当 Leader 不可用时, Follower1 和 Follower2 立即参与竞选成为主节点。Xenon校验GTID值较高的Follower 成为新主节点, 上例中GTID值较高的是Follower1 。当GTID值最高的Follower被选举成为新主时, 将结束竞选。示例中Follower1成为新主节点后, 将会拒绝 Follower2 的选举。接着, 自动完成主从切换。
2、全局事务标识符(GTID)
2.1. 什么是GTID
GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号。GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识,保存在mysql数据目录下的auto.cnf文件里。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
GTID的复制方式是从MySQL5.6.5开始的。通过GTID保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。相比传统的复制,GTID复制对于运维更加友好,根据GTID可以知道事务最初是在哪个实例上提交的,产生多少事物等,都可以非常直接的标识出来。
2.2. GTID的工作原理
大致分为如下几个步骤:
- master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
- slave端的i/o线程将变更的binlog,写入到本地的relaylog中。
- sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
- 如果有记录,说明该GTID的事务已经执行,slave会忽略。
- 中执行该GTID的事务,并记录到binlog。·如果没有记录,slave就会从relaylog
3、Mysql主从复制的三种类型
3.1. 异步复制
在mysql异步复制的情况下,Master Server将自己的binlog通过复制线程传输出去以后,MysqlMaster Sever就自动返回数据给客户端,而不管slave上是否接受到了这个二进制日志。那么,当master宕机后,如果master不能恢复,此时,只能用slave代替master,但slave处于同步落后的状态,就会导致数据丢失。
优点:复制的性能最好
缺点:master挂掉后,slave可能会丢失事务

3.2. 全同步复制
操作完数据库之后,binlog的线程会发送请求到备份节点日志,必须等待备份节点执行完成之后,主节点才能执行后续的操作
优点:数据不会丢失
缺点:性能低、非常依赖网络

3.3. 半同步复制
半同步复制,又分为两种,分别是传统半同步复制和无损半同步复制。
- 传统半同步复制
在传统半同步复制的架构下,master将自己的binlog写入到bin-log文件并且sync,且向存储引擎提交事务,然后一直等待ACK。当至少一个slave接收到binlog后,写入relay-log并返回ACK确认信息。master在接收到从库任意一个ACK确认信息后,就将结果返回给客户端。

优点:会有数据丢失风险,但很低。
缺点:会阻塞master session,性能稍差,非常依赖网络。
特点:由于master是在三段提交的最后commit阶段完成后才等待,所以master的其他session是可以看到这个提交事务的所以这时候master上的数据和slave不一致,master crash后slave有数据丢失。

- 无损半同步复制(常用)
master自己的binlog写入到binlog文件并且sync,之后会进入等待ACK,当至少一个slave接收到binlog之后,写入relay-log并返回ACK确认信息。master接收到从库ACK确认信息之后,向存储引擎提交事务,最终返回给客户端。

优点:数据零丢失,性能好
缺点:会阻塞master session,非常依赖网络
重点:由于master是在三段提交的第二阶段sync binlog完成后才等待,所以master的其他session是看不见这个提交事务的,所以这时候master上的数据和slave一致,master crash后,slave没有丢失数据。
要开启无损半同步复制,需要设置如下几个参数:
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 5000
参数rpl_semi_sync_master_wait_point在MySQL的半同步复制中,控制master在哪阶段等待来自slave的ACK确认。在MySQL5.7中,该参数主要有两个值:after_commit和after_sync。
- after_commit: 这其实就是传统的半同步复制,master将自己的binlog写入到bin-log文件并且sync,并向存储引擎提交事务,然后一直等待ACK。当至少一个slave接收到binlog后,写入relay-log并返回ACK确认信息。master在接收到从库任意一个ACK确认信息后,就将结果返回给客户端。
- after_sync: 这其实就是后面马上要讲到的无损半同步复制,master将自己的binlog写入到binlog 文件并且sync之后会进入等待ACK,当至少一个slave接收到binlog之后,写入relay-log并返回ACK确认信息。master接收到从库ACK确认信息之后,向存储引擎提交事务,最终返回给客户端。
4、xenon部署环境介绍
4.1. 系统环境说明
- 操作系统: RHEL8.3
- mysql版本: 二进制安装mysql-5.7.35
- xtrabackup: version 2.4.24
4.2. 服务器规划
服务器相关IP规划如下:
|
IP地址 |
端口号 |
主机名 |
角色 |
|
172.16.213.233 |
3306 |
xenon1 |
node节点 |
|
172.16.213.234 |
3306 |
xenon2 |
node节点 |
|
172.16.213.235 |
3306 |
xenon3 |
node节点 |
| 172.16.213.237 |
无 |
无 |
vip |
注意,这里的vip地址是跟随xenon集群启动的,默认vip会绑定在xenon选举出来的master节点上,程序要连接mysql的话,连接的就是这个vip地址。
4.3. 配置主机host
注意:需要在三个mysql节点都执行如下操作:
修改系统的/etc/hosts文件,添加如下内容:
127.0.0.1 localhost
172.16.213.233 xenon1
172.16.213.234 xenon2
172.16.213.235 xenon3
4.4. 配置SSH互信
[mysql@xenon1 ~]# ssh-keygen
[mysql@xenon1 ~]# ssh-copy-id xenon2
[mysql@xenon1 ~]# ssh-copy-id xenon3
然后在xenon2节点执行如下操作:
[mysql@xenon2 ~]# ssh-keygen
[mysql@xenon2 ~]# ssh-copy-id xenon1
[mysql@xenon2 ~]# ssh-copy-id xenon3
最后,在xenon3节点执行如下操作:
[mysql@xenon3 ~]# ssh-keygen
[mysql@xenon3 ~]# ssh-copy-id xenon1
[mysql@xenon3 ~]# ssh-copy-id xenon2
4.5. 配置mysql用户sudo权限
由于xenon在执行master、slave故障切换的时候,需要将vip地址也切换过去,而xenon是运行在mysql用户下的,所以需要给mysql用户做一个授权,让这个普通用户能够执行ip这个linux命令。
注意,下面的操作需要在三台mysql主机上都执行一遍。
这里以xenon1为例,修改/etc/sudoers文件,添加如下内容:
[root@xenon1 ~]# vi /etc/sudoers
mysql ALL=(ALL) NOPASSWD: /usr/sbin/ip
设置完成,验证下设置是否生效,执行如下操作:
[root@xenon1 ~]# su - mysql -c "sudo ip a"
如果有本机ip地址信息输出,表示配置正确。
5、xenon以及相关软件安装
5.1. 安装mysql(二进制)
不赘述前文有提及
二进制的mysql必须安装到/usr/local目录下,解压,即可完成安装,安装完成后,还需要做一些配置工作,首先是,添加mysql配置文件,这里将mysql配置文件放到/usr/local/mysql/etc/my.cnf路径下,配置文件内容如下:
[root@xenon1 ~]# vim /usr/local/mysql/etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
log-error=/usr/local/mysql/logs/mysqld.log
pid-file=/usr/local/mysql/logs/mysqld.pid
log_bin=mysql-bin
server-id=11
expire_logs_days = 10
binlog_format = row
plugin-load="semisync_master.so;semisync_slave.so"
master_info_repository = TABLE
relay_log_info_repository = TABLE
relay_log_recovery = 1
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 3000
skip-slave-start
gtid-mode = ON
enforce-gtid-consistency = ON
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers=4
slave_preserve_commit_order = 1
log-slave-updates
5.2. 安装xtrabackup
xtrabackup是mysql的一个热备份、恢复工具,xenon集成了xtrabackup,可以实现集群的备份和迁移,安装xtrabackup方法有很多,可以下载rpm包直接安装,也可以下载Percona提供的yum源进行安装,这里通过Percona提供的yum源进行安装,首先从https://www.percona.com/downloads/percona-release/ 下载Percona源,然后放到服务器上进行安装即可。
注意,xtrabackup也需要在三个集群节点进行安装。
这里以xenon1为例,其它节点安装方法相同,安装过程如下:
[root@xenon1 ~]# rpm -ivh percona-release-1.0-27.noarch.rpm
有了这个yum源后,接下来就可以安装xtrabackup了,xtrabackup目前有两个大版本,分别是percona-xtrabackup-24和percona-xtrabackup-80,其中percona-xtrabackup-80版本主要是针对mysql5.7版本进行备份,而percona-xtrabackup-80主要是针对mysql8.0以后的版本进行备份和恢复。这里我下载的是percona-xtrabackup-24,安装如下:
[root@xenon1 ~]# yum install -y percona-xtrabackup-24
安装完成后,执行如下命令,可以查看版本信息:
[root@xenon1 ~]# xtrabackup --version
xtrabackup: recognized server arguments: --datadir=/usr/local/mysql/data --server-id=11 --log_bin=/usr/local/mysql/data/mysql-bin.log
xtrabackup version 2.4.24 based on MySQL server 5.7.35 Linux (x86_64) (revision id: b4ee263)
至此,xtrabackup安装完成
5.3. 安装xenon
注意,mysql集群三个节点都需要安装编译xenon。
这里以xenon1为例,首先,安装环境依赖,主要是安装golang环境,操作如下:
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
# 安装 git
dnf install -y git
# 安装 golang(编译Xenon必须)
dnf install -y golang
然后,从https://github.com/radondb/xenon/releases/ 选择需要的版本,下载xenon源码包。
接着,就可以编译xenon了,过程如下:
[root@xenon1 ~]# mv xenon /usr/local/
[root@xenon1 ~]# cd /usr/local/xenon
[root@xenon1 ~]# make build
[root@xenon1 ~]# cd conf/
[root@xenon1 ~]# cp xenon-simple.conf.json xenon.json
---------------修改编译版本,上述是老版本---------
cd /usr/local/xenon
cp makefile makefile.bak
sed -i 's/git rev-parse/echo/g' makefile
sed -i 's/git log/echo/g' makefile
export GO111MODULE=off
export GOPATH=$(pwd)
make build
ls -lh bin/
这里将xenon安装到了/usr/local目录下,其中,xenon.json就是xenon的配置文件。记得在xenon2、xenon3节点也执行相同的操作步骤。
6、xenon配置过程详解
6.1. 配置xenon
将xenon在三个节点安装完成后,接下来,就需要配置xenon了,三个集群节点都需要配置xenon,这里以xenon1节点为例,配置好的xenon.json文件内容如下:
[root@xenon1 ~]# more /etc/xenon/xenon.json
{
"server":
{
"endpoint":"172.16.213.233:8801"
},
"raft":
{
"meta-datadir":"raft.meta",
"heartbeat-timeout":1000,
"election-timeout":3000,
"leader-start-command":"sudo /usr/sbin/ip a a 172.16.213.237/24 dev enp0s3 && arping -c 3 -A 172.16.213.237 -I enp0s3",
"leader-stop-command":"sudo /usr/sbin/ip a d 172.16.213.237/24 dev enp0s3"
},
"mysql": #三个服务器默认一样即可
{
"admin":"root",
"passwd":"abc123456",
"host":"127.0.0.1",
"port":3306,
"basedir":"/usr/local/mysql",
"defaults-file":"/usr/local/mysql/etc/my.cnf",
"ping-timeout":1000,
"master-sysvars":"super_read_only=0;read_only=0;sync_binlog=default;innodb_flush_log_at_trx_commit=default;rpl_semi_sync_slave_enabled=0;rpl_semi_sync_master_enabled=1",
"slave-sysvars": "super_read_only=1;read_only=1;sync_binlog=1000;innodb_flush_log_at_trx_commit=2;rpl_semi_sync_slave_enabled=1;rpl_semi_sync_master_enabled=0"
},
"replication": #主从复制,直接写就行
{
"user":"repl",
"passwd":"123456"
},
"backup":
{
"ssh-host":"172.16.213.233", #本地ip地址
"ssh-user":"mysql",
"ssh-passwd":"mysql123",#本机mysql用户
"ssh-port":22,
"backupdir":"/usr/local/mysql/data", #备份的默认路径
"xtrabackup-bindir":"/usr/bin",
"backup-iops-limits":100000,
"backup-use-memory": "2GB",
"backup-parallel": 2
},
"rpc":
{
"request-timeout":500
},
"log":
{
"level":"INFO"
}
}
下面解释下这个配置文件中几个重要选项的含义。
- server段中,endpoint是指定每个节点的ip和启动xenon服务对应的端口,8801端口保持默认即可。IP就是三个节点的物理IP地址,需要做修改。
- raft段中,leader-start-command选项是配置集群选举后,master节点绑定VIP地址的命令。根据前面的规划,我们使用的vip地址为172.16.213.237,注意IP的写法。leader-stop-command选项是删除VIP地址的命令。
- mysql段中,admin是指定mysql用户,一般是root,passwd是root用户的密码,这个密码在上面初始化mysql的时候做个设置,host保持默认的127.0.0.1即可,port默认是3306,basedir指定mysql库的程序根目录,我们这个环境是/usr/local/mysql,defaults-file是指定mysql库的配置文件路径,我们这里是/usr/local/mysql/etc/my.cnf。master-sysvars是设置节点变为master角色时,需要添加的mysql参数配置, 而slave-sysvars是设置slave节点mysql的参数配置。
- replication段指定的是主从复制时,对应的复制用户和密码,这个复制用户无需创建,只需要在这里指定即可,xenon会自动创建此用户以及设置用户对应的密码。
- backup段是配置xenon使用xtrabackup进行备份的相关设置,ssh-host是本机对应的IP地址,不同节点ip不同,记得修改,ssh-user是本机的linux用户,这里是mysql,ssh-passwd是mysql这个Linux用户的密码,ssh-port是ssh端口,默认是22,backupdir是指定通过xtrabackup进行备份时,备份数据的存放路径,xtrabackup在进行备份的时候,会首先删除这个路径下的所有数据,然后才开始备份。xtrabackup-bindir是指定xtrabackup这个命令所在的路径,默认是/usr/bin。
在xenon1节点配置完成后,在xenon2、xenon3节点也需要做相同的配置,记得修改配置文件中对应的ip地址。
6.2. 对xenon进行授权
先执行如下操作:
[root@xenon1 conf]# mkdir /etc/xenon/
[root@xenon1 conf]# cp /usr/local/xenon/conf/xenon.json /etc/xenon/
[root@xenon1 conf]# echo "/etc/xenon/xenon.json" > /usr/local/xenon/bin/config.path
[root@master conf]# mkdir /usr/local/xenon/logs
注意,在xenon命令路径中,需要有一个名为config的文件,否则生成集群节点时会报错。
然后,对/usr/local/xenon和/etc/xenon/目录进行授权,允许mysql用户完全访问,操作如下:
[root@xenon1 conf]# chown mysql.mysql -R /usr/local/xenon
[root@xenon1 conf]# chown mysql.mysql -R /etc/xenon/
至此,xenon配置完毕。
7、启动xenon集群与状态监控

所有配置工作完成后,就可以启动xenon集群了。首先,在172.16.213.233节点,通过mysql用户启动xenon服务,执行如下命令:
[root@xenon1 ~]# su - mysql
[mysql@xenon1 ~]$ cd /usr/local/xenon/bin
[mysql@xenon1 bin]$ ./xenon -c /etc/xenon/xenon.json > /usr/local/xenon/logs/xenon.log 2>&1 &
[mysql@xenon1 bin]$ ./xenoncli cluster add 172.16.213.233:8801,172.16.213.234:8801
注意,后面所有对集群的管理和维护操作,都通过mysql用户来完成。
这里用到了“xenoncli cluster add” 命令,这是向xenon集群中添加节点的命令,后面会多次用到。
接着,在172.16.213.233节点,查看集群状态,执行如下命令:

注意,这里用到了xenoncli cluster mysql这个命令,此命令用来查看xenon集群中mysql的状态信息。从上面输出可以看到,172.16.213.233节点角色为FOLLOWER,处于ALIVE状态,并且为READONLY(只读),而IO/SQL_Running列为true/true,表示此节点主从复制关系的IO进程和SQL进程都处于正常状态。
而172.16.213.234节点所有状态均为UNKNOW,这是因为172.16.213.234节点的xenon服务还未启动,所以集群还无法识别这个节点的状态,既然如此,下面就在172.16.213.234节点启动xenon服务,操作如下:
[root@xenon2 ~]# su - mysql
[mysql@xenon2 ~]$ cd /usr/local/xenon/bin
[mysql@xenon2 bin]$ ./xenon -c /etc/xenon/xenon.json > /usr/local/xenon/logs/xenon.log 2>&1 &
然后在172.16.213.234节点查看集群状态,执行如下命令:

从上面输出可知,172.16.213.234节点启动xenon服务后,在集群中的状态变为ALIVE,并且默认角色是FOLLOWER,同时,主从复制关系也自动建立起来了,主从状态都正常。
现在,返回172.16.213.233节点,再次查看集群状态,输出如下:

从输出可知,172.16.213.234节点从原来的UNKNOW角色变成了FOLLOWER角色,同时172.16.213.233节点的角色也从之前的FOLLOWER变成了CANDIDATE,CANDIDATE表示候选状态,也就是说xenon集群至少有两个或以上节点加入,才能进行选举,现在加入了一个,无法完成选举,所以,接下来,还需要在172.16.213.234节点将172.16.213.233节点加入集群,才能实现master和slave的选举,在172.16.213.234节点执行如下命令:
[mysql@xenon2 bin]$ ./xenoncli cluster add 172.16.213.233:8801,172.16.213.234:8801
然后在172.16.213.234节点查看集群状态,如下图所示:

从输出可知,在172.16.213.234节点将xenon1和xenon2都加入集群后,因为集群已经有了2个节点,因此可以实现正常的选举,选举的结果是172.16.213.233节点成为LEADER,也就是主从复制中的master节点,而172.16.213.234节点成为FOLLOWER角色,也就是slave节点,这样xenon集群选举就完成了。
由于我们是三个节点,所以,还需要将最后一个节点172.16.213.235也加入集群中,在xenon3执行如下命令:
[root@xenon3 ~]# su - mysql
[mysql@xenon3 ~]$ cd /usr/local/xenon/bin
[mysql@xenon3 bin]$ ./xenon -c /etc/xenon/xenon.json > /usr/local/xenon/logs/xenon.log 2>&1 &
[mysql@xenon3 bin]$ ./xenoncli cluster add 172.16.213.233:8801,172.16.213.234:8801,172.16.213.235:8801
由于有新节点加入集群,所以还需要在xenon1、xenon2节点将新的节点依次加入集群,首先在172.16.213.233节点执行如下命令:
[mysql@xenon1 bin]$ ./xenoncli cluster add 172.16.213.233:8801,172.16.213.234:8801,172.16.213.235:8801
然后在172.16.213.234节点也执行相同的命令:
[mysql@xenon2 bin]$ ./xenoncli cluster add 172.16.213.233:8801,172.16.213.234:8801,172.16.213.235:8801
最后,再返回任意一个集群节点,执行如下命令查看集群状态,输出结果如下:

从输出可知,新增的节点172.16.213.235加入集群成功,角色为FOLLOWER,处于READONLY(只读)状态,而处于LEADER 角色的节点状态为READWRITE(可读可写),这刚好就是mysql主从复制的基本运行逻辑。
要查看集群状态的详细信息,也可以执行如下命令:

“xenoncli cluster status”命令主要用来查看集群整体状态,例如每个节点的角色,mysql状态,以及目前集群中哪个是LEADER,都有清晰的输出,要进行集群故障排查,此命令会经常用到。
至此,xenon集群搭建成功。
8、xenon集群日常维护
8.1. 监控集群状态
要查看集群状态,经常执行的命令有如下几个:
[root@xenon1 ~]# su - mysql
[mysql@xenon1 ~]$ cd /usr/local/xenon/bin
[mysql@xenon1 bin]$ ./xenoncli cluster status #查看集群状态
[mysql@xenon1 bin]$ ./xenoncli cluster mysql #查看集群mysql的状态
[mysql@xenon1 bin]$ ./xenoncli cluster xenon #查看跟xenon相关的角色信息和配置
其中,“xenoncli cluster status”用来查看集群整体的状态,下图是集群某时刻的一个状态截图:

从上图可以看出,此集群中每个节点的角色、mysql运行状态、Monitor引擎是否运行、主从复制状态以及目前集群leader节点是哪个,通过此命令,集群所有状态,一目了然。
“xenoncli cluster mysql”命令,主要是查看跟mysql有关的运行状态,比如每个节点mysql角色、mysql存活状态、每个节点mysql读写权限、mysql的binlog日志回放位置、主从复制状态等信息。
而“xenoncli cluster xenon”命令,主要查看跟xenon相关的角色信息以及配置信息,如下图所示:

检查集群一致状态,可执行如下命令:
[mysql@xenon1 bin]$ ./xenoncli cluster raft
注意,上面命令是在/usr/local/xenon/bin目录下执行的,如无特殊说明,执行xenoncli命令都是在/usr/local/xenon/bin目录下完成的,下面的操作都省去了 “cd /usr/local/xenon/bin”这个步骤。
检查集群 GTID 状态,可执行如下命令:
[mysql@xenon1 bin]$ ./xenoncli cluster gtid
这个命令主要是查看集群的主从事务同步状态,下面是一个输出截图:

这里重点关注Executed_GTID_Set列和Retrieved_GTID_Set列,其中:
Retrieved_GTID_Set:表示从库已经接收到主库的事务编号。
Executed_GTID_Set :表示从库自身已经执行的事务编号。
uuid为6a2a5597-46a8-11ec-b8a2-08002735d58b的是172.16.213.233上面的mysql实例,并且三个节点都有此UUID,这说明此节点曾经是master节点(主库),6a2a5597-46a8-11ec-b8a2-08002735d58b:1-23960表示172.16.213.233这个mysql一共产生了23960个事务,并且两个slave节点接收到了主库的23960个事务,且都已全部执行。
此外,还有一个6a2a5597-46a8-11ec-b8a2-08002735d58d:1-8862的GTID,这个GTID在三个节点都有事务,查看发现GTID中的UUID刚好是172.16.213.235节点,因此,目前172.16.213.235节点是master节点(主库),并且其它两个slave节点接收到了主库的8862个事务,且都已全部执行。
Retrieved_GTID_Set列中第一行6a2a5597-46a8-11ec-b8a2-08002735d58d:523-8862表示172.16.213.233节点从172.16.213.235节点第523个事务开始接收,目前接收到了第8862个事务,从这里也可以看出,172.16.213.233应该是发生过故障,并且执行过恢复,所以接收主库的事务不是从1开始的。
Retrieved_GTID_Set列中第二行6a2a5597-46a8-11ec-b8a2-08002735d58d:1-8862表示172.16.213.234节点从172.16.213.235节点第1个事务开始接收,目前接收到了第8862个事务。
8.2. 添加/删除节点
要添加一个节点到集群,可执行如下命令:
[mysql@xenon1 bin]$ ./xenoncli cluster add 172.16.213.233:8801,172.16.213.234:8801,172.16.213.235:8801,172.16.213.232:8801
其中,172.16.213.232是新增节点,由于所有集群节点都要能够识别新增的节点,所以,添加新节点的命令,要在xenon集群每个节点都执行一遍。
要在xenon集群中删除一个节点,可以执行如下命令:
[mysql@xenon1 bin]$ ./xenoncli cluster remove 172.16.213.232:8801
要删除某个节点,只需要在集群任意节点执行上面命令即可,但,被删除的节点上,无法删除自己节点的信息,也就是说172.16.213.232这个节点被删除后,在172.16.213.232这个节点执行“xenoncli cluster mysql”这个命令时,还是能看到此节点的信息。不过不要紧,此节点既然是删除的节点,直接关闭集群服务,停止mysql服务即可,不会对集群产生影响。
8.3. Rebuild 重建节点
当某个节点发生故障时,可以通过 rebuildme重建此节点,例如某节点硬件故障,硬件恢复后,如果之前数据无法恢复,此时可以利用之前的备份,然后让此节点加入集群,最后,就可以使用rebuildme命令来将此节点恢复到最新数据状态。
在要做重建的节点执行:
[mysql@xenon1 bin]$ ./xenoncli mysql rebuildme
Xenon 重建的过程,可分为如下几个阶段:
- 禁用 raft,将 Xenon 状态设为 LEARNER;
- 如 mysql 进程存在,则 stop mysql;
- 清空 MySQL 数据目录;
- 执行 xtrabackup --backup 以 xbstream 方式获取对端数据;
- 执行 xtrabackup --prepare,应用 redo log;
- 启动 mysql;
- 执行 stop slave; reset slave all;
- 执行 reset master,以 xtrabackup_binlog_info 文件中的 GTID 为准设置 gtid_purged;
- 启用 raft,将 Xenon 状态设为 FOLLOWER 或 IDLE;
- 等待 Xenon 自动 change master to 到主节点;
- 执行 start slave。
在进行节点重建的时候,默认情况下,xenon会从集群节点中选取一个最新的slave节点进行数据复制和拷贝,但我们也可以指定从哪个节点进行数据的复制和拷贝,指定节点复制,重建当前 MySQL 节点,可通过如下方式:
[mysql@xenon1 bin]$ ./xenoncli mysql rebuildme --from=172.16.213.233:8801
注意,在执行节点重建时,此节点的mysql服务、xenon服务需要处于启动状态,也就是说重建的节点一定是集群的成员,否则无法执行重建,因此,故障节点在恢复重建之前,最好能通过之前的mysql备份,将mysql服务启动起来。然后执行重建。
8.4. 备份 MySQL到本地
xenon集成了备份功能,可以通过指定路径,将集群数据备份到某节点某路径下,操作命令如下所示:
[mysql@xenon1 bin]$ ./xenoncli mysql backup --to=/home/mysql/data
8.5. 关闭集群
在xenon集群每个节点,依次执行如下命令,即可关闭集群,这里以xenon1节点为例,命令如下:
[mysql@xenon1 bin]$ ./xenoncli mysql stopmonitor
[mysql@xenon1 bin]$ ./xenoncli mysql shutdown
[mysql@xenon1 bin]$ pkill xenon
其中,前面两个命令是关闭xenon的监控引擎、停止mysql服务,最后一个命令是关闭xenon进程。
9、xenon集群故障切换实践
9.1. 手动 Failover/switchover
xenon集群支持故障检测、故障自动切换,也支持手动触发主从切换。如果想让哪个节点成为master节点,就在哪个节点执行如下命令即可:
[mysql@xenon2 bin]$ ./xenoncli raft trytoleader
上面命令执行完成后,查看集群状态,可以发现xenon2节点目前变为集群的LEADER角色。
9.2. slave节点故障切换过程
xenon集群中,slave节点发生故障,分为几种情况:
- slave节点如果网络故障,导致主从同步中断,这个问题无需处理,只需等待网络恢复后,slave节点会自动去同步master节点的binlog数据,实现主从同步。
- 如果slave节点上mysql库异常关闭,那么xenon进程会尝试重新启动,如果能够启动mysql,那么自动恢复正常,如果xenon进程无法实现重启的,那么可能是mysql本身有故障,需要检查mysql实例,修复问题,只要mysql能够正常启动,此节点就可以正常加入集群中。
- 如果slave节点所在的主机磁盘故障,导致mysql数据丢失,或者由于redo log损坏,导 致数据库无法启动的,此种情况就需要重建此节点,这种情况也是最难处理的一种。
下面针对上面描述的第三种情况,进行恢复演练。
第一步,获取此前的数据备份,通过之前的备份数据,恢复这个节点上mysql实例的正常运行。记住,一定要通过之前对集群的备份数据进行恢复,重新初始化数据库,是无法进行恢复的。
这里假定172.16.213.234节点发生故障,此节点目前是FOLLOWER角色,也就是slave节点,首先关闭此节点的xenon服务和mysql服务(实际环境中mysql可能无法启动了),然后,将之前的备份恢复到此节点的data目录下,操作过程如下:
#关闭此节点的xenon服务和mysql服务
[mysql@xenon2 bin]$ ps -ef|grep xenon.json|grep -v grep|awk '{print $2}'|xargs kill -9
[mysql@xenon2 bin]$ /etc/init.d/mysqld stop
#把之前mysql的data目录备份,或者删除(确认可删除情况下)
[mysql@xenon2 bin]$ cd /usr/local/mysql/
[mysql@xenon2 mysql]$ mv data data.old
#将备份数据拷贝到mysql的data目录下,其中备份数据路径是/home/mysql/data
[mysql@xenon2 mysql]$ cp -r /home/mysql/data .
#数据库恢复完成后,最后一步,启动xenon服务,mysql服务会自动启动
[mysql@xenon2 data]$ cd /usr/local/xenon/bin
[mysql@xenon2 bin]$ ./xenon -c /etc/xenon/xenon.json > /usr/local/xenon/logs/xenon.log 2>&1 &
上面步骤恢复完成后,可能会自动实现master节点数据同步到此节点,那么恢复完成。但也可能出现xenon2节点主从复制失败的情况(主要是sql进程异常),失败原因是多方面的,跟使用的备份有很大关系,但解决这个问题的方法是一样的,此时需要执行第二个步骤。
第二步,如果出现了主从同步失败,那么,最快的方法,就是在这个节点执行重建,也就是在此节点执行”xenoncli mysql rebuildme“命令,但前提是此节点xenon服务和mysql服务已经正常启动。执行重建,命令如下:
[mysql@xenon2 data]$ cd /usr/local/xenon/bin
[mysql@xenon2 bin]$ ./xenoncli mysql rebuildme
执行”xenoncli mysql rebuildme“命令进行重建后,若重建成功,此节点数据和master节点完全一致。slave节点恢复成功。
9.3. master节点故障切换过程

从这个提示中,可以看出是主从复制的SQL线程报出来的异常,在执行事务6a2a5597-46a8-11ec-b8a2-08002735d58d:1时发现无法复制的错误,更详细信息,可查看performance_schema.replication_applier_status_by_worker表,执行select * from performance_schema.replication_applier_status_by_worker\G;语句,那下面就看看此表,如下图所示:

从输出可在,错误在于“'Table 'gao.k1' doesn't exist'”,也就是说,xenon1从现在的新master的binlog拉取日志,要回放gao.k1表的数据,但是发现,xenon1库中,根本没有这个表,所以发生了报错。
这种主从复制的问题发生的几率是很高的,不同的备份,可能会出现不同的问题。
出现的问题虽多,但解决方法只有一个,要解决这个问题,最简单、直接的方法就是在此节点执行重建,过程如下:
[mysql@xenon1 bin]$ ./xenoncli mysql rebuildme
2021/11/30 10:27:27.374562 [WARNING] =====prepare.to.rebuildme=====
IMPORTANT: Please check that the backup run completes successfully.
At the end of a successful backup run innobackupex
prints "completed OK!".
2021/11/30 10:27:27.375371 [WARNING] S1-->check.raft.leader
2021/11/30 10:27:27.392982 [WARNING] rebuildme.found.best.slave[172.16.213.234:8801].leader[172.16.213.235:8801]
2021/11/30 10:27:27.393014 [WARNING] S2-->prepare.rebuild.from[172.16.213.234:8801]....
2021/11/30 10:27:27.403049 [WARNING] S3-->check.bestone[172.16.213.234:8801].is.OK....
2021/11/30 10:27:27.403075 [WARNING] S4-->set.learner
2021/11/30 10:27:27.404604 [WARNING] S5-->stop.monitor
2021/11/30 10:27:27.405926 [WARNING] S6-->kill.mysql
2021/11/30 10:27:27.488928 [WARNING] S7-->check.bestone[172.16.213.234:8801].is.OK....
2021/11/30 10:27:27.504558 [WARNING] S8-->clear.datadir[/usr/local/mysql/data]
2021/11/30 10:27:27.541446 [WARNING] S9-->xtrabackup.begin....
2021/11/30 10:27:27.542133 [WARNING] rebuildme.backup.req[&{From: BackupDir:/usr/local/mysql/data SSHHost:172.16.213.233 SSHUser:mysql SSHPasswd:mysql123 SSHPort:22 IOPSLimits:100000 XtrabackupBinDir:/usr/bin}].from[172.16.213.234:8801]
2021/11/30 10:27:44.235087 [WARNING] S9-->xtrabackup.end....
2021/11/30 10:27:44.235131 [WARNING] S10-->apply-log.begin....
2021/11/30 10:27:50.200013 [WARNING] S10-->apply-log.end....
2021/11/30 10:27:50.200058 [WARNING] S11-->start.mysql.begin...
2021/11/30 10:27:50.201383 [WARNING] S11-->start.mysql.end...
2021/11/30 10:27:50.201402 [WARNING] S12-->wait.mysqld.running.begin....
2021/11/30 10:27:53.250253 [WARNING] wait.mysqld.running...
2021/11/30 10:27:53.331268 [WARNING] S12-->wait.mysqld.running.end....
2021/11/30 10:27:53.331286 [WARNING] S13-->wait.mysql.working.begin....
2021/11/30 10:27:56.332544 [WARNING] wait.mysql.working...
2021/11/30 10:27:56.333433 [WARNING] S13-->wait.mysql.working.end....
2021/11/30 10:27:56.333458 [WARNING] S14-->stop.and.reset.slave.begin....
2021/11/30 10:27:56.615532 [WARNING] S14-->stop.and.reset.slave.end....
2021/11/30 10:27:56.615562 [WARNING] S15-->reset.master.begin....
2021/11/30 10:27:56.856596 [WARNING] S15-->reset.master.end....
2021/11/30 10:27:56.856704 [WARNING] S15-->set.gtid_purged[6a2a5597-46a8-11ec-b8a2-08002735d58b:1-23960,
6a2a5597-46a8-11ec-b8a2-08002735d58d:1-522
].begin....
2021/11/30 10:27:56.898296 [WARNING] S15-->set.gtid_purged.end....
2021/11/30 10:27:56.898326 [WARNING] S16-->enable.raft.begin...
2021/11/30 10:27:56.900621 [WARNING] S16-->enable.raft.done...
2021/11/30 10:27:56.900646 [WARNING] S17-->wait[3000 ms].change.to.master...
2021/11/30 10:27:56.900690 [WARNING] S18-->start.slave.begin....
2021/11/30 10:27:57.274490 [WARNING] S18-->start.slave.end....
2021/11/30 10:27:57.274519 [WARNING] completed OK!
2021/11/30 10:27:57.274529 [WARNING] rebuildme.all.done....
从这个输出可知,在执行重建过程中,xenon自动从集群最新节点172.16.213.234:8801进行数据读取和备份,然后将数据复制到xenon1节点上,最后重建成功。
这个恢复过程其实是利用了之前的数据备份,由此可知,在xenon集群中,一定要定期做数据备份,这样在某节点出现问题的时候,可以通过备份来进行恢复。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)