*主要做的就是主从切换*
主数据库服务器宕机后的操作;一次性;
自行删除宕机后的主数据库的(server1)配置文件
该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)。
(目前MHA主要支持多一主多从的架构,至少3台,一台主数据库,一台中继,一台从。)
且在三台数据库服务器上都要去配备MHA NODE(方便故障后根据节点辨析二进制日志文件)
Manager 可以单独部署在一台独立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。
MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测集群中的 master 节点,当 master 出现故障时,它可以自动将最新数据的slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。
在 MHA 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。
例如,如果主服务器硬件故障或无法通过 ssh 访问,MHA 没法保存二进制日志,只进行故障转移而丢失了最新的数据。
使用 MySQL 5.5 开始的*半同步复制*,可以大大降低数据丢失的风险。
如果只有一个 slave 已经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的 slave 服务器上,因此可以保证所有节点的数据一致性
目前 MHA 主要支持一主多从的架构,要搭建 MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当 master,一台充当备用 master,另外一台充当从库。
MHA 适合任何存储引擎, 只要能主从复制的存储引擎它都支持,不限于支持事物的 innodb 引擎。
相对比其它 HA 软件,MHA 的目的在于维持 MySQL Replication 中 Master 库的高可用性,其*最大特点*是可以修复多个 Slave 之间的差异日志,最终使所有 Slave 保持数据一致,然后从中选择一个充当新的 Master,并将其它 Slave 指向它。(会自行解决主服务器宕机后的主从配置;一次性的)
(1)从宕机崩溃的 master 保存二进制日志事件(binlog events);
(2)*识别含有最新更新的 slave*;
(3)应用差异的中继日志(relay log)到其他的 slave;
(4)应用从 master 保存的二进制日志事件(binlog events);
(5)*提升一个 slave 为新的 master*;
(6)*使其他的 slave 连接新的 master 进行复制*;
最大好处:选择slave为master,且恢复主从关系(新的master)
MHA 软件组成
Manager 工具包和 Node 工具包
角色 | 主机名 | Ip | 类型 | Software |
---|---|---|---|---|
master | Weiyi5 | 192.168.106.101 | 主mysql(写) | Mha4mysql-node |
Slave1 | Weiyi7 | 192.168.106.103 | 中继mysql(读) | Mha4mysql-node |
Slave2 | Weiyi8 | 192.168.106.104 | 从mysql(读) | Mha4mysql-node |
Mha | Weiyi6 | 192.168.106.106 | 管理节点 | Mha4mysql-node;manage |
master 对外提供写服务, slave1 提供读服务,slave2 也提供读服务,一旦 master宕机,将会把其中一个 slave 提升为新的 master,其他 slave 指向新的 master。
同步时间(所有服务时间同步,网络同步或者手动修改)
[root@Weiyi5~]# yum install -y ntp
[root@Weiyi5~]# ntpdate ntp1.aliyun.com
这一步可以开启xshell中的工具中的全部执行~
Systemctl stop firewalld (可用工具全发)
Systemctl disable firewalld
Setenforce 0 (可用工具全发)
(因为数据库以及所搭建的MHA都为ssh的安全链接,彼此之间若主机宕机,提升后的二进制文件也是运用ssh去进行拉取,故彼此之间需要实现ssh免密登录。)
注意:四台之间都需要是ssh免密登录!!为自己也要保存!
该操作打开xhell的工具并发~ (不然四台上一一进行该操作)
[root@Weiyi5~]# ssh-keygen -t rsa
[root@Weiyi5~]# ssh-copy-id 192.168.1.11
[root@Weiyi5~]# ssh-copy-id 192.168.1.12
[root@Weiyi5~]# ssh-copy-id 192.168.1.13
[root@Weiyi5~]# ssh-copy-id 192.168.1.14
mha4mysql-node-0.57-0.el7.noarch.rpm
mha4mysql-manager-0.57-0.el7.noarch.rpm
mhapath.tar.gz
[root@Weiyi6~]# tar -zxvf mhapath.tar.gz
[root@Weiyi6~]# *vim /etc/yum.repos.d/mhapath.repo*
[mha]
name=mhapath
baseurl=file:///root/mhapath
enabled=1
gpgcheck=0
[root@Weiyi6~]# *vim /etc/yum.repos.d/centos.repo*
[centos7]
name=centos_7
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0
[root@Weiyi6~]# mount /dev/sr0 /mnt/cdrom/
(四台机子都需要进行挂载;有的已经在。Etc/fstab中进行开机自挂~)
[root@Weiyi6~]# for ip in 101 104 103 ; do scp -r /etc/yum.repos.d/* 192.168.106.$ip:/etc/yum.repos.d/ ; done
[root@Weiyi6~]# for ip in 101 104 103 ; do scp -r /root/mhapath 192.168.106.$ip:/root ; done
[root@Weiyi6~]# for ip in 101 104 103 ; do scp /root/mha4mysql-node-0.57-0.el7.noarch.rpm 192.168.106.$ip:/root ; done
在数据库节点只要安装 MHA 的 node 工具包,在管理节点需要安装 manager 工具包和 node 工具包。
[root@Weiyi6~]# for ip in 101 103 104 106; do ssh 192.168.106.$ip "yum -y install perl-DBDMySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager --skip-broken --nogpgcheck;rpm -ivh mha4mysql-node-0.57-0.el7.noarch.rpm"; done
安装完成后会在/usr/bin/目录下生成以下脚本文件
[root@Weiyi6~]# ll /usr/bin/{app*,filter*,purge*,save*}
-rwxr-xr-x 1 root root 16381 5 月 31 2015 /usr/bin/apply_diff_relay_logs
-rwxr-xr-x 1 root root 4807 5 月 31 2015 /usr/bin/filter_mysqlbinlog
-rwxr-xr-x 1 root root 8261 5 月 31 2015 /usr/bin/purge_relay_logs
-rwxr-xr-x 1 root root 7525 5 月 31 2015 /usr/bin/save_binary_logs
MHA Manager 中主要包括了几个管理员的命令行工具,例如 master_manger,
master_master_switch 等。MHA Manger 也依赖于 perl 模块。
[root@Weiyi6~]# yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes perl-ExtUtils-CBuilder perl-ExtUtilsMakeMaker perl-CPAN
[root@Weiyi6~]# rpm -ivh mha4mysql-manager-0.57-0.el7.noarch.rpm
安装完成后会在/usr/bin 目录下面生成以下脚本文件
[root@Weiyi6~]# ll /usr/bin/masterha*
-rwxr-xr-x 1 root root 1995 5 月 31 2015 /usr/bin/masterha_check_repl
-rwxr-xr-x 1 root root 1779 5 月 31 2015 /usr/bin/masterha_check_ssh
-rwxr-xr-x 1 root root 1865 5 月 31 2015 /usr/bin/masterha_check_status
-rwxr-xr-x 1 root root 3201 5 月 31 2015 /usr/bin/masterha_conf_host
-rwxr-xr-x 1 root root 2517 5 月 31 2015 /usr/bin/masterha_manager
-rwxr-xr-x 1 root root 2165 5 月 31 2015 /usr/bin/masterha_master_monitor
-rwxr-xr-x 1 root root 2373 5 月 31 2015 /usr/bin/masterha_master_switch
-rwxr-xr-x 1 root root 5171 5 月 31 2015 /usr/bin/masterha_secondary_check
-rwxr-xr-x 1 root root 1739 5 月 31 2015 /usr/bin/masterha_stop
为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置 MHA 的同时建议配置成 MySQL 的半同步复制。mysql 半同步插件是由谷歌提供,具体位置/usr/local/mysql/lib/plugin/下,一个是master 用的 semisync_master.so,一个是 slave 用的 semisync_slave.so.
所有 mysql 数据库服务器安装半同步插件(同样可以调用工具中的全发,进行此项操作)
[root@Weiyi5~]# mysql -uroot -p123456 -e "install plugin rpl_semi_sync_master
soname 'semisync_master.so';install plugin rpl_semi_sync_slave soname
'semisync_slave.so';"
[root@Weiyi7~]# mysql -uroot -p123456 -e "install plugin rpl_semi_sync_master
soname 'semisync_master.so';install plugin rpl_semi_sync_slave soname
'semisync_slave.so';"
[root@Weiyi8~]# mysql -uroot -p123456 -e "install plugin rpl_semi_sync_master
soname 'semisync_master.so';install plugin rpl_semi_sync_slave soname
'semisync_slave.so';"
[root@Weiyi5~]# mysql -uroot -p123456 -e "show plugins;" | grep rpl_semi_sync*
[root@Weiyi5~]# mysql -uroot -p123456 -e "show variables like '%rpl_semi_sync%';"
上图可以看到半同复制插件已经安装,只是还没有启用,所以是 off
配置 my.cnf(因为后期宕机后*可能成为从*,*所以binglong,relaylog都要配置*)
[root@Weiyi5~]# vim /etc/my.cnf
server-id=1
log-bin=/data/mysql/log/mysql-bin
log-bin-index=/data/mysql/log/mysql-bin.index
binlog_format=mixed
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000
rpl_semi_sync_slave_enabled=1
relay_log_purge=0
relay-log = /data/mysql/log/relay-bin
relay-log-index = /data/mysql/log/slave-relay-bin.index
binlog-do-db=HA #可以被从服务器复制的库。二进制需要同步的数据库名
log_slave_updates=1 #只有开启 log_slave_updates,从库 binlog 才会记录主库同步的
操作日志
注:相关参数解释
rpl_semi_sync_master_enabled=1 1 表是启用,0 表示关闭
rpl_semi_sync_master_timeout=10000 毫秒单位,该参数表示主服务器等待确认
消息,10 秒后,不再等待,变为异步方式。
[root@Weiyi5~]# systemctl restart mysqld
[root@Weiyi5~]# mysql -uroot -p123456
mysql> create database HA;
mysql> use HA;
mysql> create table test(id int,name varchar(20));
mysql> insert into test values(1,'tom1')
mysql> grant replication slave on . to slave@'192.168.106.%' identified by '123456';
mysql> grant all privileges on . to *root*@'192.168.106.%' identified by '123456'; (给mha的用户;可以是其他用户,但要有root权限)
mysql> flush privileges;
[root@Weiyi5~]#里的mysql ;mysql> show master status;
(看主的日志记录在哪个00000x;以及节点号,在配置从数据库的时候会用到。)
[root@Weiyi5~]# mysqldump -uroot -p123456 -B HA>HA.sql
[root@Weiyi5~]# scp HA.sql [email protected]:~
[root@Weiyi5~]# scp HA.sql [email protected]:~
[root@Weiyi7~]# mysql -uroot -p123456
[root@Weiyi7~]# vim /etc/my.cnf
server-id=2
log-bin=/data/mysql/log/mysql-bin
log-bin-index=/data/mysql/log/mysql-bin.index
binlog_format=mixed
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000
rpl_semi_sync_slave_enabled=1
relay_log_purge=0
relay-log=/data/mysql/log/relay-bin
relay-log-index=/data/mysql/log/slave-relay-bin.index
binlog-do-db=HA
log_slave_updates=1 #只有开启 log_slave_updates,从库 binlog 才会记录主库同步的
操作日志
[root@Weiyi7~]# systemctl restart mysqld
(因为所有的从服务器都可能提升为主服务器,所以从服务器也需要创建同步账号)
[root@Weiyi7~]# mysql -uroot -p123456
mysql> grant replication slave on . to slave@'192.168.106.%' identified by '123456';
mysql> grant all privileges on . to root@'192.168.106.%' identified by '123456';
mysql> flush privileges;
mysql> stop slave;
mysql> change master to
master_host='192.168.1.101',master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=1500;
(如果上面不去导入ha。sql,要去主的看一下show master status的节点!!!!,日志里面有创建语句了;最好还是去导入)
mysql> start slave;
mysql> show slave status\G
查看i/o;以及sql是否为yes
[root@Weiyi8~]# mysql -uroot -p123456
server-id=3
log-bin=/data/mysql/log/mysql-bin
log-bin-index=/data/mysql/log/mysql-bin.index
binlog_format=mixed
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000
rpl_semi_sync_slave_enabled=1
relay_log_purge=0
relay-log = /data/mysql/log/relay-bin
relay-log-index = /data/mysql/log/slave-relay-bin.index
binlog-do-db=HA #可以被从服务器复制的库。二进制需要同步的数据库名
log_slave_updates=1 #只有开启 log_slave_updates,从库 binlog 才会记录主库同步的
操作日志
[root@Weiyi8~]# systemctl restart mysqld
(每个从之后都可能为主;在配置文件中也要相似;授权用户这一步骤也需要有)
[root@Weiyi8~]# mysql -uroot -p123456
mysql> grant replication slave on . to slave@'192.168.106.%' identified by '123456';
mysql> grant all privileges on . to root@'192.168.106.%' identified by '123456';
mysql> flush privileges;
建立主从关系
mysql> stop slave;
mysql> change master to
master_host='192.168.1.101',master_user='slave',master_password='123456',master_lo
g_file='mysql-bin.000001',master_log_pos=1500;
mysql> start slave;
mysql> show slave status\G;
从库对外提供读服务,只所以没有写进配置文件,是因为 slave 随时会提升为master
[root@Weiyi7~]# mysql -uroot -p123456 -e 'set global read_only=1'
[root@Weiyi8~]# mysql -uroot -p123456 -e 'set global read_only=1'
14) 查看半同步相关信息
[root@Weiyi5~]# mysql -uroot -p123456 -e "show variables like '%rpl_semi_sync%';"
[root@Weiyi5~]# mysql -uroot -p123456 -e "show status like '%rpl_semi_sync%';"
[root@Weiyi6~]# mkdir -p /etc/masterha
[root@Weiyi6~]# mkdir -p /var/log/masterha/app1
[root@Weiyi6~]# vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
master_binlog_dir=/data/mysql/log
#master_ip_failover_script=/usr/bin/master_ip_failover
#master_ip_online_change_script=/usr/bin/master_ip_online_change
user=root
password=123456
ping_interval=1
remote_workdir=/tmp
repl_user=slave
repl_password=123456
report_script=/usr/local/send_report
shutdown_script=""
ssh_user=root
[server1]
hostname=192.168.106.101
port=3306
[server2]
hostname=192.168.106.103
port=3306
[server3]
hostname=192.168.106.104
检查 MHA Manger 到所有 MHA Node 的 SSH 连接状态:
[root@Weiyi6~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
*如果报错:请检查你所有节点是不是都配置了 SSH 免密登陆*
[root@Weiyi6~]# masterha_check_repl --conf=/etc/masterha/app1.cnf
注:如果报如下错误(检测第二次就会报错)
这是因为之前健康检查报错,需要删除之前健康检查的文件
[root@Weiyi6~]# rm -rf /var/log/masterha/app1/app1.master_status.health
[root@Weiyi6~]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 is stopped(2:NOT_RUNNING).
注意:如果正常,会显示"PING_OK",否则会显示"NOT_RUNNING",这代表 MHA
监控没有开启
[root@Weiyi6~]# 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 &
[1] 43664
启动参数介绍:
--remove_dead_master_conf 该参数代表当发生主从切换后,老的主库的 ip
将会从配置文件中移除。
--manger_log 日志存放位置
--ignore_last_failover 在缺省情况下,如果 MHA 检测到连续发生宕机,
且两次宕机间隔不足 8 小时的话,则不会进行 Failover 故障转移,该参数代表忽略
上次 MHA 触发切换产生的文件。默认情况下,MHA 发生切换后会在日志目录,也
就是上面设置的/data 产生 app1.failover.complete 文件,下次再次切换的时候如果
发现该目录下存在该文件将不允许触发切换,除非在第一次切换后删除该文件,为
了方便,这里设置为--ignore_last_failover。
[root@Weiyi6~]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:43664) is running(0:PING_OK), master:192.168.106.101
可以看见已经在监控了,而且 master 的主机为 192.168.106.101
[root@Weiyi6~]# tail -20 /var/log/masterha/app1/manager.log
[root@Weiyi6~]# masterha_stop --conf=/etc/masterha/app1.cnf
[root@Weiyi6~]# 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 &
[1] 44107
1) 打开新窗口观察日志
[root@Weiyi6~]# tail -0f /var/log/masterha/app1/manager.log
2) 模拟主库挂掉
[root@Weiyi5~]# systemctl stop mysqld
3) 看日志是否切换 master 成功
可以看到 master 已经切换到 192.168.106.103
登陆从 Weiyi7查看 show slave status\G 是否成功切换
[root@Weiyi8~]# mysql -uroot -p123456 -e "show slave status\G"
*vim /etc/masterha/app1.cnf**里 的配置的原本的server1,系统自 己将其删除了!!查看一下 vim / etc/masterha/app1.cnf没有了*
4) 查看 Weiyi7 主从状态
[root@Weiyi7~]# mysql -uroot -p123456 -e "show processlist \G"
发现只剩下 Weiyi8 的 slave,MHA 把原先的 master(Weiyi5)踢掉了
[root@Weiyi7~]# mysql -uroot -p123456 -e "show master status;"
使用 VIP(虚拟ip) 可以实现 mysql master 服务器的高可用。
vip 配置可以采用两种方式,一种通过 keepalived 的方式管理虚拟 ip 的浮动;另外一种通过脚本方式启动虚拟 ip 的方式(即不需要 keepalived 或者 heartbeat 类似的软件)。
为了防止脑裂发生,推荐环境采用脚本的方式来管理虚拟 ip,而不是使用keepalived 来完成。
[root@Weiyi7~]# ifconfig ens33:1 192.168.106.88 netmask 255.255.255.0 up
[root@Weiyi7~]# ifconfig ens33:1
在主配置文件添加自动切换切换脚本,恢复 Weiyi5,把它设为 slave
[root@Weiyi6~]# vim /etc/masterha/app1.cnf
master_ip_failover_script=/usr/bin/master_ip_failover
[server1]
hostname=192.168.106.101
port=3306
[root@Weiyi5~]# systemctl start mysqld
[root@Weiyi5~]# mysql -uroot -p123456
mysql> stop slave;
mysql> change master to
master_host='192.168.1.12',master_user='slave',master_password='123456',master_lo
g_file='mysql-bin.000001',master_log_pos=890;
mysql> start slave;
mysql> set global read_only=1;
mysql> show slave status\G;
使用的 vip 是 192.168.106.88/24
[root@Weiyi6~]# vim /usr/bin/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.106.88/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\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";
#ssh $ssh_user\@cluster1 \" $ssh_start_vip \";
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
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";
}
[root@Weiyi6~]# chmod +x /usr/bin/master_ip_failover
[root@Weiyi6~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
[root@Weiyi6~]# rm -rf /var/log/masterha/app1/app1.master_status.health
[root@Weiyi6~]# masterha_check_repl --conf=/etc/masterha/app1.cnf
[root@Weiyi6~] 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 &
[1] 44422
[root@Weiyi6~] masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:44422) is running(0:PING_OK), master:192.168.1.12
[root@Weiyi6~] tail -0f /var/log/masterha/app1/manager.log
9) 模拟主库挂掉
10) 关闭 mysql 主服务器
[root@Weiyi7~] systemctl stop mysqld
11) 查看日志是否切换 master 成功
[root@Weiyi5~] mysql -uroot -p123456 -e "show master status\G"
12) 在 Weiyi8 查看主是否切换成功
[root@Weiyi8~] mysql -uroot -p123456 -e "show slave status\G"
13) 查看 Weiyi5 主从状态
[root@Weiyi5~] mysql -uroot -p123456 -e "show processlist \G"
14) 查看 VIP 是否漂移过来 (*从mha漂移到新主上面,mha上没有了*)
[root@Weiyi5~] ifconfig ens33:1