MySQL高可用,顾名思义就是当MySQL主机或服务发生任何故障时能够立马有其他主机顶替其工作,并且最低要求是要保证数据一致性。因此,对于一个MySQL高可用系统需要达到的目标有以下几点:
(1)数据一致性保证这个是最基本的同时也是前提,如果主备的数据不一致,那么切换就无法进行,当然这里的一致性也是一个相对的,但是要做到最终一致性。
(2)故障快速切换,当master故障时这里可以是机器故障或者是实例故障,要确保业务能在最短时间切换到备用节点,使得业务受影响时间最短。
(3)简化日常维护,通过高可用平台来自动完成高可用的部署、维护、监控等任务,能够最大程度的解放DBA手动操作,提高日常运维效率。
(4)统一管理,当复制集很多的情况下,能够统一管理高可用实例信息、监控信息、切换信息等。
(5)高可用的部署要对现有的数据库架构无影响,如果因为部署高可用,需要更改或者调整数据库架构则会导致成本增加。
目前MySQL高可用方案可以一定程度上实现数据库的高可用,比如MMM,heartbeat+drbd,NDB Cluster等。还有MariaDB的Galera Cluster,以及MySQL 5.7.17 Group Replication等。这些高可用软件各有优劣。在进行高可用方案选择时,主要是看业务对数据一致性方面的要求。最后出于对数据库的高可用和高可靠的要求,目前推荐使用MHA架构,因为MySQL GP还不能在生产使用,但是相信以后慢慢就会被用到生产环境的。
MHA(Master High Availability) 目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。除了failover之外,MHA还支持在线master切换,非常安全和高效,大概只需要(0.5 ~ 2秒)的阻塞写时间。
(1)master自动监控,故障转移一体化(Automated master monitoring and failover)
(2)MHA可以在一个复制组中监控master的状态,如果挂了,就可以自动的做failover。
(3)MHA通过所有slave的差异relay-log来保证数据的一致性。
(4)MHA在做故障转移,日志补偿这些动作的时候,通常只需要10~30秒。
(5)通常情况下,MHA会选择最新的slave作为new master,但是你也可以指定哪些是候选maser,那么新master选举的时候,就从这些host里面挑。
(6)导致复制环境中断的一致性问题,在MHA中是不会发生的。
在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5及以上版本的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。
(7)手工-交互式master故障转移(Interactive manually initiated Master Failover)
MHA可以配置成手工-交互式方式进行故障转移,不支持监控master的状态。
(8)非交互式master故障转移 (Non-interactive master failover)
非交互式,自动的故障转移,不提供监控master状态功能,监控可以交给其他组件做(如:Pacemaker heartbeat)。
(9)在线master切换 (Online switching master to a different host)
如果你有更快,更好的master,计划要将老master替换成新的master,那么这个功能特别适合这样的场景。
这不是master真的挂掉了,只是我们有很多需求要进行master例行维护。
该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明
目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当slave。当然,如果你处于成本考虑,也可以使用两个节点的MHA,一主一从(实测过的)。
详解
实验说明:
对一主多从的集群数据库进行高可用管理,需要一台MHA管理服务器,以及集群的数据库服务器(三台)
角色 | 服务器 | ip |
---|---|---|
master | server1 | 172.25.254.121 |
slave | server2 | 172.25.254.122 |
slave | server3 | 172.25.254.123 |
manager | server4 | 172.25.254.124 |
管理实验一:基于gtid主从复制的半自动MHA管理
gtid主从复制的实现
在server1:
systemctl stop mysqld ##如果之前环境做过其他实验,最好重新启动新的mysqld
cd /var/lib/mysql/
rm -fr *
systemctl start mysqld
cat /var/log/mysqld.log|grep password
mysql_secure_installation ##初始化
vim /etc/my.cnf ##编辑配置文件
在server2:
cat /var/log/mysqld.log|grep password
mysql_secure_installation ##初始化
vim /etc/my.cnf ##编辑配置文件
在server3:
cat /var/log/mysqld.log|grep password
mysql_secure_installation ##初始化
vim /etc/my.cnf ##编辑配置文件
集群服务器免密切换的实现
manager要实现对集群服务器的管理就要对他们都实现免密登录
在server4:
(1)下载MHA管理软件
[root@mysql4 .ssh]# yum install mha4mysql-manager-0.58-0.el7.centos.noarch.rpm perl-* mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
(2)生成连接密钥将,并将密钥给管理的服务器
[root@mysql4 .ssh]# ssh-keygen
[root@mysql4 masterha]# ssh-copy-id [email protected]:
[root@mysql4 masterha]# ssh-copy-id [email protected]:
[root@mysql4 masterha]# ssh-copy-id [email protected]:
(3)创建masterha配置目录,写配置文件
[root@mysql4 .ssh]# mkdir /etc/masterha
[root@mysql4 .ssh]# cd /etc/masterha
[root@mysql4 masterha]# vim app1.cnf
[server default]
manager_workdir=/etc/masterha
manager_log=/var/log/masterha.log
master_binlog_dir=/etc/masterha
#master_ip_failover_script= /usr/local/bin/master_ip_failover
#master_ip_online_change_script= /usr/local/bin/master_ip_online_change
password=Westos+001 ##登录数据库密码
user=root ##登录数据库用户身份
ping_interval=1
remote_workdir=/tmp
repl_password=Westos+001 ##主从复制使用密码
repl_user=repl ##主从复制master授权用户
#report_script=/usr/local/send_report
#secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02
#shutdown_script=""
ssh_user=root ##连接用户身份
[server1] ##管理的服务器server1(master)
hostname=172.25.254.121
port=3306
[server2] ##服务器server2(slave)
hostname=172.25.254.122
port=3306
candidate_master=1 ##当master接替master
check_repl_delay=0
[server3]
hostname=172.25.254.123
port=3306
no_master=1 ##no_master表示这个节点不能作为master
(4)ssh连接检测
[root@mysql4 ~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
发现报错,server1,server2,server3之间不能免密连接,但这是我们需要的,保证更高效更快速的服务
(5)将密钥文件发送给集群服务器,保证服务器之间可以免密连接
[root@mysql4 ~]# scp -r .ssh [email protected]:
[root@mysql4 ~]# scp -r .ssh [email protected]:
[root@mysql4 ~]# scp -r .ssh [email protected]:
(6)再次检测ssh连接
[root@mysql4 masterha]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
手动死切的实现
手动死切表示,当我们的master宕机后,我们通过masterha手动切换master
(1)对manager_node各节点安装类似manager管理的一个接口软件
[root@mysql1 MHA-7]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
[root@mysql2 MHA-7]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
[root@mysql3 MHA-7]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm
(2)对mnager管理复制进行健康检查
[root@mysql4 masterha]# masterha_check_repl --conf=/etc/masterha/app1.cnf
(3)模拟master(server1)宕机,手动切换master
在server1:
[root@mysql1 .ssh]# systemctl stop mysqld
在server4:
[root@mysql4 masterha]# masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --dead_master_host=172.25.254.121 --dead_master_ip=172.25.254.121 --dead_master_port=3306 --new_master_host=172.25.254.122 --new_master_port=3306
查看master是否切换成功:
在server3:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.19.122
Master_User: repl19
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000003
Read_Master_Log_Pos: 1165
Relay_Log_File: mysql3-relay-bin.000003
Relay_Log_Pos: 445
Relay_Master_Log_File: binlog.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
此时master已经切换到server2上,server1在宕机后就从集群服务中被踢出去了,我们需要恢复它,手动让他继续加入集群:
在server1:
[root@mysql1 .ssh]# systemctl start mysqld ##重新启动服务
[root@mysql1 .ssh]#mysql -uroot -pWestos+0019 ##登录数据库,设定server1为新slave
mysql> change_master to
-> master_host='172.25.19.122',
-> master_user='repl19',
-> master_password='Westos+0019',
-> master_auto_position=1;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.19.122
Master_User: repl19
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000003
Read_Master_Log_Pos: 1165
Relay_Log_File: mysql1-relay-bin.000003
Relay_Log_Pos: 445
Relay_Master_Log_File: binlog.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
手动活切的实现
手动活切代表在所有集群服务器都正常的情况下,对master进行切换
在server4:(在之前实现基础上,先前实验后master在server2上)
[root@mysql4 masterha]# masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=172.25.254.121 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
在server3查看master情况:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.19.121
Master_User: repl19
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 438
Relay_Log_File: mysql3-relay-bin.000002
Relay_Log_Pos: 405
Relay_Master_Log_File: binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
管理实验二:基于gtid主从复制的自动MHA管理
vip的设定
在真正的生产环境中,我们的ip资源是非常有限的,一个集群服务应该是只有只个vip面向客户的,因此设定vip模拟master服务器宕机vip的漂移,虽然服务master发生了变化,但这对客户来说是感觉不到任何变化的。
(1)配置文件的配置
[root@mysql4 masterha]# ls ##每次切换master后都会生成app1.failover.complete文件,可以将其删除,防止影响其它操作
app1.cnf app1.failover.complete
[root@mysql4 masterha]# rm -fr app1.failover.complete
[root@mysql4 masterha]# ls
app1.cnf
[root@mysql4 ~]#vim /etc/masterha/masterha.cfg
[root@mysql4 ~]# cd mysql/
[root@mysql4 mysql]# ls
master_ip_failover mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar sysbench
master_ip_online_change mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
MHA-7 send_report
[root@mysql4 mysql]# vim master_ip_failover ##修改添加vip策略
13 my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
14 my $ssh_stop_vip = "/sbin/ip addr add $vip dev eth0";
[root@mysql4 mysql]# vim master_ip_online_change
9 my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
10 my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";
[root@mysql4 mysql]# cp master_ip_failover master_ip_online_change /usr/local/bin/
[root@mysql4 mysql]# cd /usr/local/bin ##将脚本绝对路径要与配置文件中的位置相同
[root@mysql4 bin]# ls
master_ip_failover master_ip_online_change
[root@mysql4 bin]# chmod +x master_ip_failover ##给脚本相应执行权限
[root@mysql4 bin]# chmod +x master_ip_online_change
(2)给master添加vip(此时master为server1)
[root@mysql1 .ssh]# ip addr add 172.25.254.100/24 dev eth0
[root@mysql1 .ssh]# ip addr show eth0
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:62:e9:c7 brd ff:ff:ff:ff:ff:ff
inet 172.25.254.121/16 brd 172.25.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.25.254.100/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe62:e9c7/64 scope link
valid_lft forever preferred_lft forever
(3)vip飘移测试
在server4:
masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=172.25.254.122 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
在server1查看:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.19.122
Master_User: repl19
Master_Port: 3306
在server2查看:
[root@mysql2 .ssh]# ip addr show eth0
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:d8:15:96 brd ff:ff:ff:ff:ff:ff
inet 172.25.19.122/16 brd 172.25.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.25.19.100/24 scope global eth0
valid_lft forever preferred_lft forever
inet 172.25.0.100/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fed8:1596/64 scope link
valid_lft forever preferred_lft forever
在server3:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.19.122
Master_User: repl19
自动切换
自动切换即表示开启MHA在master宕机后,manager自动切换master
(1)开启MHAmanager自动切换功能
[root@mysql4 masterha]# nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null >/var/log/masterha.log 2>&1 &
[1] 13157
(2)模拟master宕机,自动切换的实现
[root@mysql1 .ssh]# systemctl stop mysqld
在server3:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.19.122
Master_User: repl19
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 234
Relay_Log_File: mysql3-relay-bin.000002
Relay_Log_Pos: 361
Relay_Master_Log_File: binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
master成功自动切换