1. MHA集群概述
集群的定义:多台服务器一起提供相同的服务,如(web集群)等。 常见集群的分类: LB(负载均衡集群):服务器共同平均分摊处理客户端的多次连接请求。 HA(高可用集群):主备模式,主宕机后备用服务器自动接替工作。 常见集群服务软件: LB:LVS、Nginx、haproxy等。 HA:Keepalived、heartbeat、
1.1. 软件介绍
MHA(Master High Availability)
由日本DeNA公司youshimaton通过perl脚本语言开发。 是一套优秀的实现MySQL高可用的解决方案。 数据库的自动故障切换操作能做到在0~30秒之内完成。 MHA能确保在故障切换过程中最大限度保证数据的一致性,以达到真正意义的高可用。
1.2. MHA组成
管理所有数据库服务器 可以单独部署在一台独立的机器上 也可以部署在某台数据库服务器上
存储数据的MySQL服务器 运行在每台MySQL服务器上
1.3. MHA工作过程
MHA集群架构图: MHA 工作过程:
由Manager 定时探测集群中的master节点 当master故障时,Manager自动将拥有最新数据的slave提升为新的master,另一台slave主机将自动变为新master的从库,所以集群组里面的主机应该是一主多从结构。
1.4. IP规划
IP地址 主从同步角色 集群角色 主机名 192.168.2.10 客户端 无 client10 192.168.2.20 无 管理主机 mha20 192.168.2.30 主库 当前主库 mysql30 192.168.2.40 从库 备用主库 mysql40 192.168.2.50 从库 备用主库 mysql50 192.168.2.100 无 VIP地址 无
2. 部署MHA集群
2.1. 准备集群环境
2.1.1. 安装依赖包
[ root@mha20 ~]
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Email-Date-Format-1.002-15.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Mail-Sender-0.8.23-1.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Mail-Sendmail-0.79-21.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-MIME-Lite-3.030-1.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-MIME-Types-1.38-2.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
wget http://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/perl-Config-Tiny-2.14-7.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm[ root@mha20 ~]
perl-Config-Tiny-2.14-7.el7.noarch.rpm perl-Mail-Sendmail-0.79-21.el7.noarch.rpm
perl-Email-Date-Format-1.002-15.el7.noarch.rpm perl-MIME-Lite-3.030-1.el7.noarch.rpm
perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm perl-MIME-Types-1.38-2.el7.noarch.rpm
perl-Mail-Sender-0.8.23-1.el7.noarch.rpm perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
[ root@mha20 ~]
2.1.2. 配置ssh密钥对认证登录
配置管理主机mha20可以ssh免密登录所有数据库服务器
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mysql30 ~]
[ root@mysql30 ~]
[ root@mysql30 ~]
[ root@mysql40 ~]
[ root@mysql40 ~]
[ root@mysql40 ~]
[ root@mysql50 ~]
[ root@mysql50 ~]
[ root@mysql50 ~]
2.1.3. 配置一主多从
2.1.3.1. 配置主库(mysql30)
[ root@mysql30 ~]
[ mysqld]
.. ..
log_bin = mysql30
server_id = 30
plugin-load= rpl_semi_sync_master= semisync_master.so; rpl_semi_sync_slave = semisync_slave.so
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_slave_enabled = 1
relay_log_purge = 0
[ root@mysql30 ~]
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql30.000001 | 154 | | | |
+----------------+----------+--------------+------------------+-------------------+
1 row in set ( 0.00 sec)
mysql> grant replication slave on *.* to 'master' @'%' identified by '1234' ;
2.1.3.2. 配置从服务器(mysql40)
[ root@mysql40 ~]
[ mysqld]
.. ..
server_id = 40
log_bin = master40
plugin-load= rpl_semi_sync_master= semisync_master.so; rpl_semi_sync_slave = semisync_slave.so
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_slave_enabled = 1
relay_log_purge = 0
[ root@mysql40 ~]
mysql> change master to-> master_host = "192.168.2.30" ,-> master_user = "master" ,-> master_password = "1234" ,-> master_log_file = "mysql30.000001" ,-> master_log_pos = 154 ;
mysql> start slave;
Query OK, 0 rows affected ( 0.01 sec)
mysql> show slave status\ G;
查看Slave_IO_Running和Slave_SQL_Running是yes那就配置成功,这里不展示了。
2.1.3.3. 配置从服务器(mysql50)
[ root@mysql50 ~]
[ mysqld]
.. ..
server_id = 50
log_bin = master50
plugin-load= rpl_semi_sync_master= semisync_master.so; rpl_semi_sync_slave = semisync_slave.so
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_slave_enabled = 1
relay_log_purge = 0
[ root@mysql50 ~]
mysql> change master to-> master_host = "192.168.2.30" ,-> master_user = "master" ,-> master_password = "1234" ,-> master_log_file = "mysql30.000001" ,-> master_log_pos = 154 ;
mysql> start slave;
Query OK, 0 rows affected ( 0.01 sec)
mysql> show slave status\ G;
查看Slave_IO_Running和Slave_SQL_Running是yes那就配置成功,这里不展示了。
2.2. 配置管理节点(mha20)
2.2.1. 安装mha软件包
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 ~]
2.2.2. 管理集群命令
[ root@mha20 ~]
masterha_check_repl masterha_check_status masterha_manager masterha_master_switch masterha_stop
masterha_check_ssh masterha_conf_host masterha_master_monitor masterha_secondary_check
命令 作用 masterha_check_ssh 检查MHA的SSH配置状态 masterha_check_repl 检查MySQL复制状态 masterha_manager 启动MHA masterha_check_status 检测MHA运行状态 masterha_stop 停止MHA masterha_master_monitor 检测master是否宕机 masterha_master_switch 控制故障转移(自动或者手动) masterha_conf_host 添加或删除配置的server信息
2.2.3. 修改主配置文件
[ root@mha20 ~]
[ root@mha20 ~]
[ root@mha20 mha]
修改内容如下:
[ server default] ---管理服务的默认配置
manager_workdir = /etc/mha ---指定工作目录路径
manager_log = /etc/mha/manager.log ---指定管理服务运行后日志文件的名称和存放路径
master_ip_failover_script = /etc/mha/master_ip_failover ---指定故障切换脚本
ssh_user = root ---指定ssh连接时候的用户名和端口号
ssh_port = 22 repl_user = master ---指定主库授权的用户名和密码
repl_password = 1234 user = mysqldb ---指定监控用户和密码,三台mysql需要一样。
password = 1234 ping_interval = 1 ---ping间隔时长
[ server1] ---指定第一台mysql服务器
hostname = 192.168 .2.30 ---指定第一台mysqlIP地址
port = 3306 ---端口号
candidate_master = 1 ---指定该数据库服务器参与竞选主库,1代表参与。[ server2]
hostname = 192.168 .2.40
port = 3306
candidate_master = 1 [ server3]
hostname = 192.168 .2.50
port = 3306
candidate_master = 1
2.2.4. 创建故障切换脚本
[ root@mha20 mha]
[ root@mha20 mha]
[ root@mha20 mha]
use strict;
use warnings FATAL = > 'all' ; use Getopt::Long; my ( $command , $ssh_user , $orig_master_host , $orig_master_ip ,$orig_master_port , $new_master_host , $new_master_ip , $new_master_port
) ; my $vip = '192.168.2.100/24' ;
my $key = '1' ;
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip " ;
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down" ; GetOptions( 'command=s' = > \ $command ,'ssh_user=s' = > \ $ssh_user ,'orig_master_host=s' = > \ $orig_master_host ,'orig_master_ip=s' = > \ $orig_master_ip ,'orig_master_port=i' = > \ $orig_master_port ,'new_master_host=s' = > \ $new_master_host ,'new_master_ip=s' = > \ $new_master_ip ,'new_master_port=i' = > \ $new_master_port ,
) ; exit & main( ) ; sub main { print "\n \n IN SCRIPT TEST====$ssh_stop_vip ==$ssh_start_vip ===\n \n " ; if ( $command eq "stop" || $command eq "stopssh" ) { my $exit_code = 1 ; eval { print "Disabling the VIP on old master: $orig_master_host \n " ; & stop_vip( ) ; $exit_code = 0 ; } ; if ( $@ ) { warn "Got Error: $@ \n " ; exit $exit_code ; } exit $exit_code ; }
elsif ( $command eq "start" ) { my $exit_code = 10 ; eval { print "Enabling the VIP - $vip on the new master - $new_master_host \n " ; & start_vip( ) ; $exit_code = 0 ; } ; if ( $@ ) { warn $@ ; exit $exit_code ; } exit $exit_code ; } elsif ( $command eq "status" ) { print "Checking the Status of the script.. OK \n " ; exit 0 ; } else { & usage( ) ; exit 1 ; }
}
sub start_vip ( ) { ` ssh $ssh_user\ @$new_master_host \ " $ssh_start_vip \ "` ;
}
sub stop_vip ( ) { return 0 unless ( $ssh_user ) ; ` ssh $ssh_user\ @$orig_master_host \ " $ssh_stop_vip \ "` ;
} sub usage { print"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n " ;
}
2.2.5. 在主库上创建VIP地址(mysql30)
[ root@mysql30 ~]
[ root@mysql30 ~]
ens33:1: flags = 416 3 < UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168 .2.100 netmask 255.255 .255.0 broadcast 192.168 .2.255ether 00:0c:29:88:4f:b0 txqueuelen 1000 ( Ethernet)
2.3. 配置数据库服务器(mysql30-50)
2.3.1. 在数据库服务器安装mha4mysql-node软件包
[ root@mysql30 ~]
[ root@mysql30 ~]
2.3.2. 创建监控用户
mysql> grant all on *.* to 'mysqldb' @'%' identified by '1234' ;
Query OK, 0 rows affected, 1 warning ( 0.00 sec)
3. 验证配置
3.1. 测试ssh配置
[ root@mha20 ~]
.. ..
All SSH connection tests passed successfully ---最后出现这个就说明配置正确。
3.2. 测试主从配置
[ root@mha20 ~]
.. .
MySQL Replication Health is OK. ---出现这个说明MySQL复制运行状况正常
3.3. 启动管理服务
使用 masterha_manager 命令启动管理服务
—— --remove_dead_master_conf是指当主库宕机的时候,会删除宕机主库的配置,否则主库宕机后服务就会无法启动;–ignore_last_failover是指忽略 xxx.health 文件,意思是当主库宕机之后,服务会在规定的时间内连接剩下的从服务器来选举出主库。如果启动服务的时候不加这个选项,那么超过规定时间还没连接上的时候,就不会再去切换主库了,加上这个选项后,既是在规定时间内没能连接上剩下的从服务器,之后也会继续尝试连接,知道选举出主库进行切换。
[ root@mha20 ~]
nohup masterha_manager --conf = /etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover &
[ root@mha20 ~]
app1 ( pid:39934) is running( 0 :PING_OK) , master:192.168.2.30
[ root@mha20 ~]
4 测试高可用
4.1. 模拟主库服务器故障
停止mysqld服务 关机 故障切换过程: 当管理主机连接不上mysql主服务器时,就认为mysql主服务器宕机了,然后管理主机的服务自动停掉,然后调用故障切换脚本,删除管理主机中关于mysql主服务器的内容(/etc/mha/app1.cnf)然后脚本会在选举出来的主服务器创建VIP地址。
[ root@mysql30 ~]
[ root@mha20 ~]
[ root@mha20 ~]
Fri Feb 24 14 :58:16 2023 - [ info] Searching new master from slaves..
192.168 .2.40( 192.168 .2.40:3306) ( new master)
Fri Feb 24 14 :58:16 2023 - [ info] Getting new master's binlog name and position..
Enabling the VIP - 192.168 .2.100/24 on the new master - 192.168 .2.40
Fri Feb 24 14 :58:17 2023 - [ info] Resetting slave 192.168 .2.50( 192.168 .2.50:3306) and starting replication from the new master 192.168 .2.40( 192.168 .2.40:3306) ..
Fri Feb 24 14 :58:18 2023 - [ info] Resetting slave info on the new master..
Selected 192.168 .2.40( 192.168 .2.40:3306) as a new master.
[ root@mysql40 ~]
ens33:1: flags = 416 3 < UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168 .2.100 netmask 255.255 .255.0 broadcast 192.168 .2.255ether 00:0c:29:83:e3:d4 txqueuelen 1000 ( Ethernet)
[ root@mysql50 ~]
mysql: [ Warning] Using a password on the command line interface can be insecure.Master_Host: 192.168 .2.40 ---可以看的出来mysql40已经是masterl Master_User: masterMaster_Port: 3306 Connect_Retry: 60 Master_Log_File: master40.000001Read_Master_Log_Pos: 154 Relay_Log_File: mysql50-relay-bin.000002Relay_Log_Pos: 319 Relay_Master_Log_File: master40.000001Slave_IO_Running: YesSlave_SQL_Running: Yes
[ root@mha20 ~]
[ root@mha20 ~]
app1 ( pid:57758) is running( 0 :PING_OK) , master:192.168.2.40
4.2. 修复故障的数据库服务器
4.2.1. 数据服务器的配置
启动mysql服务 与主服务器数据一致 指定主服务器信息 启动slave进程 查看slave状态信息
[ root@mysql30 ~]
mysql> change master to-> master_host = "192.168.2.40" ,-> master_user = "master" ,-> master_password = "1234" ,-> master_log_file = "master40.000001" ,-> master_log_pos = 154 ;
Query OK, 0 rows affected, 2 warnings ( 0.00 sec)
mysql> start slave;
4.2.2. 配置管理主机
[ root@mha20 ~]
[ root@mha20 ~]
.. ..
[ server1]
candidate_master = 1
hostname = 192.168 .2.30
port = 3306
[ root@mha20 ~]
[ root@mha20 ~]
app1 ( pid:60567) is running( 0 :PING_OK) , master:192.168.2.40