目录
2. 修改 Master、Slave1、Slave2 节点的主机名
(2) 在 Master节点Mysql1上停止mysql服务
一、MHA
1、MHA定义
MHA(MasterHigh Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。MHA 的出现就是解决MySQL 单点的问题。MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用。
MHA 是由日本人 yoshinorim(原就职于DeNA现就职于FaceBook)开发的比较成熟的 MySQL 高可用方案。MHA 能够在30秒内实现故障切换,并能在故障切换中,最大可能的保证数据一致性。目前淘宝也正在开发相似产品 TMHA, 目前已支持一主一从。
2.工作原理
MHA工作原理总结为以下几条:
- 从宕机崩溃的 master 保存二进制日志事件(binlog events);
- 识别含有最新更新的 slave ;
- 应用差异的中继日志(relay log) 到其他 slave ;
- 应用从 master 保存的二进制日志事件(binlog events);
- 提升一个 slave 为新 master ;
- 使用其他的 slave 连接新的 master 进行复制。
3.MHA组成
(1)MHA Node(数据节点)
MHA Node 运行在每台 MySQL 服务器上。它通过监控具备解析和清理 logs 功能的脚本来加快故障转移。
(2)MHA Manager(管理节点)
MHA Manager 可以单独部署在一台独立的机器上,管理多个 master-slave 集群;也可以部署在一台 slave 节点上。
MHA Manager 会定时探测集群中的 master 节点。当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。
4.MHA服务角色
主要是接收管理节点所发出指令的代理,代理需要运行在每一个 mysql 节点上。简单讲 node 就是用来收集从节点服务器上所生成的 bin-log 。对比打算提升为新的主节点之上的从节点的是否拥有并完成操作,如果没有发给新主节点在本地应用后提升为主节
由上图我们可以看出,每个复制组内部和 Manager 之间都需要ssh实现无密码互连,只有这样,在 Master 出故障时, Manager 才能顺利的连接进去,实现主从切换功能。
5.MHA特点(作用)
(1)自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
(2)使用半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性
(3)目前MHA支持一主多从架构,最少三台服务,即一主两从
二、MHA的搭建
master服务器: 192.168.174.10 已安装mysql5.7
slave1服务器: 192.168.174.20 已安装mysql5.7
slave2服务器: 192.168.174.30 已安装mysql5.7
1.初始化环境
[root@localhost ~]# systemctl stop firewalld 关闭防火墙
[root@localhost ~]# setenforce 0 关闭selinux安全
软链接
ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
2. 修改 Master、Slave1、Slave2 节点的主机名
[root@localhost ~]# hostnamectl set-hostname mysql1/mysql2/mysql3
[root@localhost ~]# su
[root@localhost ~]# vim /etc/hosts
192.168.174.10 mysql1
192.168.174.20 mysql2
192.168.174.30 mysql3
3.主从同步
(1)搭建时间同步,(主从都安装)
[root@mysql1 ~]# yum install ntp -y 安装时间同步服务器
- 主服务器
1.修改配置文件
[root@mysql1 ~]#vim /etc/ntp.conf
server 127.127.174.0
fudge 127.127.174.0 stratum 8
2.开启服务
[root@mysql1 ~]#service ntpd start
- 从服务器
1.安装同步服务
[root@mysql2/3 ~]#yum install ntpdate -y
2.开启服务
[root@mysql2/3 ~]#service ntpd start
3.执行同步
[root@mysql2/3 ~]#/usr/sbin/ntpdate 192.168.174.10
4.设置定时任务
[root@mysql2/3 ~]# crontab -e
(2) 配置主从(开启二进制日志)
- 主服务器
1.进入配置文件
[root@mysql1 ~]# vim /etc/my.cnf
[mysqld]
server-id = 1
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.indexbinlog_format=MIXED
log-slave-updates=true
2.重启服务
[root@localhost ~]#systemctl restart mysqld
3.进入数据库
[root@localhost ~]#mysql -uroot(因为我在my.cnf中设置了跳过密码,所以免密登录)
免密:skip-name-resolve,skip-grant-tables
4.授权主用户
mysql> flush privileges;
mysql> grant replication slave on *.* to 'myslave'@'192.168.174.%' identified by '123456';
mysql> show master status;
授权主从用户
mysql> grant all privileges on *.* to 'mha'@'192.168.174.%' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql1' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql2' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql3' identified by 'manager';
- 从服务器
1.进入修改配置文件
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
server-id = 2 另一台从服务器为3
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.indexbinlog_format=MIXED
log-slave-updates=true
2.重启服务
[root@localhost ~]# systemctl restart mysqld.service
3. 进入数据库
[root@localhost ~]#mysql -uroot
mysql> help change master to
mysql>change master to master_host='192.168.174.10',master_user='myslave',master_password='123456',master_log_file='master-bin.000002',master_log_pos=1842; 这里要与主查看的一致
授权主从用户
mysql> flush privileges;
mysql> grant all privileges on *.* to 'mha'@'192.168.174.%' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql1' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql2' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql3' identified by 'manager';
mysql> start slave; 开启从服务
mysql> show slave status\G 显示
mysql> set global read_only=1; 节点只读模式
(3)验证
- 主服务器
[root@localhost ~]#mysql -uroot
mysql> create database ky15;
mysql> show databases;
- 从服务器
[root@localhost ~]#mysql -uroot
mysql> show databases;
4.安装MHA
(1)在所有的服务器上都安装MHA依赖的环境
安装epel源
[root@mysql1/2/3以及localhost~]# yum install epel-release --nogpgcheck -y
[root@mysql1/2/3以及localhost~]# yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN
(2)在所有的服务器上都安装 node 组件
导入node和manager压缩包
[root@mysql1/2/3以及localhost~]# tar zxvf mha4mysql-node-0.57.tar.gz
[root@mysql1/2/3以及localhost~]# cd mha4mysql-node-0.57
[root@mysql1/2/3以及localhost mha4mysql-node-0.57]# perl Makefile.PL
[root@mysql1/2/3以及localhost mha4mysql-node-0.57]# make && make install[root@mysql1/2/3以及localhost mha4mysql-node-0.57]# cd
[root@mysql1/2/3以及localhost~]#
[root@mysql1/2/3以及localhost~]#cd mha4mysql-manager-0.57/
[root@mysql1/2/3以及localhost mha4mysql-manager-0.57/]#perl Makefile.PL
[root@mysql1/2/3以及localhost mha4mysql-manager-0.57/]#make && make install[root@mysql1/2/3以及localhost mha4mysql-manager-0.57/]#cd /usr/local/bin
PS:在所有服务器上必须先安装 node 组件,最后在 MHA-manager 节点上安装 manager 组件,因为 manager 依赖 node 组件
(3)在所有服务器上配置无密码认证
在manager节点上配置到所有数据库节点的无密码认证
[root@localhost bin]# ssh-keygen -t rsa
[root@localhost bin]# ssh-copy-id 192.168.174.10
[root@localhost bin]# ssh-copy-id 192.168.174.20
[root@localhost bin]# ssh-copy-id 192.168.174.30
同理
在master上
[root@mysql1 ~]# ssh-keygen -t rsa
[root@mysql1 ~]# ssh-copy-id 192.168.174.20
[root@mysql1 ~]# ssh-copy-id 192.168.174.30
在slave1上
[root@mysql2 ~]# ssh-keygen -t rsa
[root@mysql2 ~]# ssh-copy-id 192.168.174.10
[root@mysql2 ~]# ssh-copy-id 192.168.174.30
在slave2上
[root@mysql3 ~]# ssh-keygen -t rsa
[root@mysql3 ~]# ssh-copy-id 192.168.174.10
[root@mysql3 ~]# ssh-copy-id 192.168.174.20
我们可以在各个服务器上以ssh + 被连机器的IP即可验证
(4)在manager节点上操作
在manager节点上复制相关脚本到/usr/local/bin 目录
[root@localhost ~]# cp -rp mha4mysql-manager-0.57/samples/scripts /usr/local/bin
这里拷贝后会有四个执行文件
ll /usr/local/bin/scripts/ (用此命令查看)
master_ip_failover 自动切换时 VIP 管理的脚本
master_ip_online_change 在线切换时 vip 的管理
power_manager 故障发生后关闭主机的脚本
send_report 因故障切换后发送报警的脚本
复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录
[root@localhost ~]# cp /usr/local/bin/scripts/* /usr/local/bin
修改master_ip_failover 全部删除,添加以下内容,修改相关参数
[root@localhost ~]# cd /usr/local/bin/scripts/
[root@localhost scripts]# vim master_ip_failover
#!/usr/bin/env perl 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.174.188'; my $brdc = '192.168.174.255'; my $ifdev = 'ens33'; my $key = '1'; my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip"; my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down"; my $exit_code = 0; #my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;"; #my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key"; ################################################################################## 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\nIN 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 \"`; } ## A simple system call that disable the VIP on the old_master sub stop_vip() { `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"; }
创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器
创建 MHA 软件目录并拷贝配置文件
[root@localhost ~]# cd mha4mysql-manager-0.57/samples/conf/
[root@localhost conf]# mkdir /etc/masterha
[root@localhost conf]# cp app1.cnf /etc/masterha/
修改app1.cnf配置文件,删除原文所有内容,添加下面的内容
vim /etc/masterha/app1.cnf
[server default] manager_log=/var/log/masterha/app1/manager.log manager_workdir=/var/log/masterha/app1 master_binlog_dir=/usr/local/mysql/data master_ip_online_change_script=/usr/local/bin/master_ip_online_change password=manager ping_interval=1 remote_workdir=/tmp repl_password=123456 repl_user=myslave report_script=/usr/local/send_report secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.174.20 -s 192.168.174.30 shutdown_script="" ssh_user=root user=mha [server1] hostname=192.168.174.10 port=3306 [server2] candidate_master=1 check_repl_delay=0 hostname=192.168.174.20 port=3306 [server3] hostname=192.168.174.30 port=3306
在主节点开启虚拟IP
[root@mysql1 ~]# ifconfig ens33:1 192.168.174.188/24
在manager节点上测试ssh无密码认证
[root@localhost scripts]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
在manager节点上测试 mysql 主从连接情况
[root@localhost scripts]# masterha_check_repl -conf=/etc/masterha/app1.cnf
如果出现问题可以访问来解决masterha_check_repl --conf=/etc/masterha/app1.cnf的各种报错及解决方法_黄如果的博客-CSDN博客
在manager节点上启动 MHA
[root@localhost scripts]# nohup masterha_manager --conf=/etc/masterha/app1.cnf -- remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
查看MHA状态,可以看到当前的 master是Mysql1节点
[root@localhost scripts]# masterha_check_status --conf=/etc/masterha/app1.cnf
查看 MHA 日志,也以看到当前的 master 是 192.168.174.10
[root@localhost scripts]# cat /var/log/masterha/app1/manager.log | grep "current master"
查看Mysql1的VIP地址 192.168.174.188是否存在
[root@mysql1 ~]# ifconfig
三、故障的模拟与恢复
1.故障模拟
(1)在manager节点上监控观察日志记录
[root@localhost scripts]# tail -f /var/log/masterha/app1/manager.log
(2) 在 Master节点Mysql1上停止mysql服务
[root@mysql1 ~]# systemctl stop mysqld
[root@mysql1 ~]# ifconfig
(3)在slave1,slave2上查看
2. 故障修复
(1)修复mysql1
[root@mysql1 ~]# systemctl restart mysqld
(2)修复主从
在现主库服务器Mysql2查看二进制文件和同步点
[root@mysql2 ~]# show master status;
在原主库服务器 mysql1 执行同步操作
mysql> change master to master_host='192.168.174.20',master_user='myslave',master_password='123456' master_log_file='master-bin.000002',master_log_pos=1842;
mysql> start slave;
mysql> show slave status\G;
在manager节点上修改配置文件app1.cnf
在manager节点上启动 MHA 就恢复了
[root@localhost scripts]# nohup masterha_manager --conf=/etc/masterha/app1.cnf -- remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &