一、MHA架设
MHA(Master High Availability)是一种实现基于主从复制实现MySQL故障切换的架构。当主节点发生故障时,会自动切换到一个从节点,然后将该从节点选为主节点。
1. 架设主从复制
MySQL主节点:192.168.1.131
MySQL从节点:192.168.1.132、192.168.1.133
1.1 配置主节点
-
编辑主节点的my.cnf文件,开启二进制日志文件,并允许从节点将写入自己二进制日志,并开启普通日志。
server-id=1 log-bin=master-bin binlog_format=MIXED log-slave-updates=true relay_log_recovery=1 general_log=ON general_log_file=/usr/local/mysql/data/mysql.log
-
重启MySQL服务。
systmctl restart mysqld
1.2 配置从节点
-
配置从节点服务器的my.cnf文件。其中一台的id设置为2,一台的id设置为3。
# 从节点1 # 配置二进制日志、中继日志、普通日志 server-id = 2 log-bin=master-bin binlog-format=MIXED relay-log=relay-log-bin relay-log-index=slave-relay-bin.index relay_log_recovery = 1 general_log=ON general_log_file=/usr/local/mysql/data/mysql.log # 从节点2 # 配置中继日志文件、普通日志 server-id = 3 relay-log=relay-log-bin relay-log-index=slave-relay-bin.index relay_log_recovery = 1 general_log=ON general_log_file=/usr/local/mysql/data/mysql.log
-
重启MySQL服务。
systmctl restart mysqld
1.3 配置访问用户
-
在三台MySQL中创建主从复制的用户,并授权。
mysql">CREATE USER 'myslave'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY '123456'; GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.1.%'; FLUSH PRIVILEGES;
-
在三台MySQL中创建MHA的用户,并授权。
mysql">CREATE USER 'mha'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'manager'; GRANT ALL PRIVILEGES ON *.* TO 'mha'@'192.168.1.%' WITH GRANT OPTION; FLUSH PRIVILEGES;
1.4 配置主从复制
-
在主节点终端中查看主节点状态。
mysql">SHOW MASTER STATUS;
-
登录从节点的MySQL终端,同步主节点。
mysql">CHANGE master to master_host='192.168.1.131',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=845;
-
在两个从节点的MySQL终端中启动从节点,查看状态。
mysql">start slave; show slave status\G; # 状态信息中的I/O和SQL线程均为Yes时,表名成功同步 Slave_IO_Running: Yes Slave_SQL_Running: Yes
1.5 验证主从复制
-
在主节点上登录MySQL终端,创建一个数据库。
mysql">CREATE DATABASE test;
-
在从节点的终端中查看数据库是否存在。
mysql">SHOW DATABASES;
2. 架设MHA
MySQL主节点:192.168.1.131
MySQL从节点:192.168.1.132、192.168.1.133
MHA管理节点:192.168.1.128
VIP:192.168.1.100
2.1 安装MHA软件
-
在四台节点上安装所需要的依赖环境和工具。
apt install -y libdbd-mysql-perl libconfig-tiny-perl liblog-dispatch-perl libparallel-forkmanager-perl libextutils-cbuilder-perl libmodule-install-perl make
-
在四个MySQL节点上编译安装MHA Node。
tar -zxvf mha4mysql-node-0.57.tar.gz cd mha4mysql-node-0.57 perl Makefile.PL make && make install
-
在MHA管理节点上再另外安装MHA Manager。
tar -zxvf mha4mysql-manager-0.57.tar.gz cd mha4mysql-manager-0.57 perl Makefile.PL make && make install
2.2 配置免密认证
-
在MHA Manager上配置三个MySQL节点的免密。
ssh-keygen -t rsa ssh-copy-id 192.168.1.131 ssh-copy-id 192.168.1.132 ssh-copy-id 192.168.1.133
-
在MySQL主节点上配置两个从节点的免密。
ssh-keygen -t rsa ssh-copy-id 192.168.1.132 ssh-copy-id 192.168.1.133
-
在MySQL从节点1上配置另外两个节点的免密。
ssh-keygen -t rsa ssh-copy-id 192.168.1.131 ssh-copy-id 192.168.1.133
-
在MySQL从节点2上配置另外两个节点的免密。
ssh-keygen -t rsa ssh-copy-id 192.168.1.131 ssh-copy-id 192.168.1.132
2.3 配置MHA Manager
-
复制MHA Manager的脚本目录到/usr/local/bin目录下。
cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
-
将自动切换时管理VIP的脚本master_ip_failover到/usr/local/bin目录下。
cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
-
修改文件内容,配置VIP等。
#!/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.1.100'; my $brdc = '192.168.1.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; 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管理目录,将管理MySQL的配置文件复制到该目录下。
mkdir /etc/masterha cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
-
修改该文件内容。
[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_failover_script=/usr/local/bin/master_ip_failover 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 secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.1.132 -s 192.168.1.133 shutdown_script="" ssh_user=root user=mha [server1] hostname=192.168.1.131 port=3306 [server2] candidate_master=1 check_repl_delay=0 hostname=192.168.1.132 port=3306 [server3] hostname=192.168.1.133 port=3306
-
修改/usr/local/share/perl/5.34.0/MHA/NodeUtil.pm文件,将188行开始的5行配置改成如下内容。
sub parse_mysql_major_version($) { my $str = shift; $str =~ /(\d+)\.(\d+)/; my $strmajor = "$1.$2"; my $result = sprintf( '%03d%03d', $1, $2 ) if $str =~ m/(\d+)\.(\d+)/; return $result; }
2.4 配置VIP和软链接
-
在MySQL主节点上配置VIP。
ifconfig ens33:1 192.168.1.100
-
在三个MySQL节点上创建mysql、mysqlbinlog命令的软链接。
ln -s /usr/local/mysql/bin/mysql /usr/sbin/ ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
2.5 测试MHA
-
在MHA管理节点上执行下面的命令,检测SSH是否能够正常免密认证。
masterha_check_ssh -conf=/etc/masterha/app1.cnf # 出现下面的信息表示正常 All SSH connection tests passed successfully.
-
在MHA管理节点上执行下面的命令,检测MySQL的连接是否正常。
masterha_check_repl -conf=/etc/masterha/app1.cnf # 出现下面的信息表示正常 MySQL Replication Health is OK.
-
如果显示apply_diff_relay_logs未找到命令,大部分情况是因为MySQL节点上的MHA Node没有成功安装。
通常节点没有安装MHA Node会显示未在对应节点上找到Node,如果没有显示则可能是某个节点出现了伪安装,也就是节点的系统环境存在问题。MHA Node看似成功安装,但是所需的一些环境不存在。
解决方法就是使用yum、apt或其他方式重新下载软件所需的依赖环境。
-
2.6 MHA的基本使用
-
后台启动MHA。
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状态。
masterha_check_status --conf=/etc/masterha/app1.cnf
-
关闭MHA。
masterha_stop --conf=/etc/masterha/app1.cnf
二、MHA故障模拟及恢复
1. 故障模拟
-
在MHA管理节点上实时查看日志文件。
tail -f /var/log/masterha/app1/manager.log
-
MHA正常启动后,关闭MySQL主节点上的MySQL服务。
systemctl stop mysqld
-
观察MHA的日志消息,看到主节点宕机,从节点被选为主节点。
Master 192.168.1.131(192.168.1.131:3306) is down! …… Selected 192.168.1.132(192.168.1.132:3306) as a new master.
-
完成主节点的切换后,MHA会结束运行。与此同时,配置文件中的app1.cnf中,关于宕机主节点的信息会被删除。
-
再次查看网卡信息,发现VIP地址转移到了新的主节点上。
2. 故障恢复
-
重启关闭的MySQL服务。
systemctl restart mysqld
-
在新的MySQL主节点上查看主节点状态。
mysql">SHOW MASTER STATUS;
-
在原主节点上同步主节点数据。
mysql">CHANGE master to master_host='192.168.1.132',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=157;
-
启动从节点,查看状态。
mysql">start slave; show slave status\G;
-
修改MHA管理节点上的app1.cnf文件。
# 修改IP地址为两个新的从节点IP secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.1.131 -s 192.168.1.133 # 将删除的节点信息加回来 [server1] hostname=192.168.1.131 port=3306
-
重新启动MHA。
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 &