简介
MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能。MHA 在监控到 master 节点故障时,会提升其中拥有最新数据的 slave 节点成为新的master 节点,在此期间,MHA 会通过于其它从节点获取额外信息来避免一致性方面的问题。MHA 还提供了 master 节点的在线切换功能,即按需切换 master/slave 节点。
MHA 是由日本人 yoshinorim(原就职于DeNA现就职于FaceBook)开发的比较成熟的 MySQL 高可用方案。MHA只负责Mysql主库的高可用,主库发生故障时, MHA会选择一个数据最接近原主库的候选节点作为新的主节点,并补齐和之前Dead Master差异的Binlog, 数据补齐之后,将写vip飘逸到新主库上对外提供服务.
MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库上(通过将从库提升为主库)大概0.5-2秒即可完成.
MHA原理
服务角色
MHA服务有两种角色, MHA Manager(管理节点)和MHA Node(数据节点)
MHA Manager
通常单独部署在一台独立机器上管理多个 master/slave 集群(组),每个 master/slave 集群称作一个 application,用来管理统筹整个集群。
MHA node
运行在每台 MySQL 服务器上(master/slave/manager),它通过监控具备解析和清理 logs 功能的脚本来加快故障转移
主要是接收管理节点所发出指令的代理,代理需要运行在每一个 mysql 节点上。简单讲 node 就是用来收集从节点服务器上所生成的 bin-log 。对比打算提升为新的主节点之上的从节点的是否拥有并完成操作,如果没有发给新主节点在本地应用后提升为主节点。
由上图我们可以看出,每个复制组内部和 Manager 之间都需要ssh实现无密码互连,只有这样,在 Master 出故障时, Manager 才能顺利的连接进去,实现主从切换功能。
/*
当Master出现故障时,他可以自动将最新数据的Slave提升为新的Master,然后将所有其他的Slave重新指向新的Master, 整个故障转移过程对应的程序是完全透明的.
*/
工作原理
# MHA工作原理总结为以下几条:
# 1 从宕机崩溃的 master 保存二进制日志事件(binlog events);
# 2 识别含有最新更新的 slave ;
# 3 应用差异的中继日志(relay log) 到其他 slave ;
# 4 应用从 master 保存的二进制日志事件(binlog events);
# 5 提升一个 slave 为新 master ;
# 6 使用其他的 slave 连接新的 master 进行复制。
在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性
环境配置
MHA 对 MYSQL 复制环境有特殊要求,例如各节点都要开启二进制日志及中继日志,各从节点必须显示启用其read-only属性,并关闭relay_log_purge功能等,这里对配置做事先说明。
主机名
IP
服务角色
备注
Manager
192.168.43.125
Manager控制器
监控管理
master
192.168.43.241
数据库主
slave1
192.168.43.183
数据库从
slave2
192.168.43.252
数据库从
配置ssh免密
注意是四台机器互相喔
echo -e "\n" |ssh-keygen -t dsa -N ""
ssh-copy-id -i .ssh/id_dsa.pub slave1
ssh-copy-id -i .ssh/id_dsa.pub slave2
ssh-copy-id -i .ssh/id_dsa.pub master
准备Mysql主从复制环境
注意
binlog-do-db 和 replicate-ignore-db 设置必须相同。 MHA 在启动时候会检测过滤规则,如果过滤规则不同,MHA 不启动监控和故障转移
安装mysql
tar xf mysql-5.7.25-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
useradd mysql -s /sbin/nologin -M
mv mysql-5.7.25-linux-glibc2.12-x86_64 /usr/local/mysql
cd /usr/local/mysql
mkdir logs
\cp support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chown -R mysql:mysql /usr/local/mysql/
ln -s /usr/local/mysql/bin/* /usr/local/bin/
chkconfig --add mysqld
mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
`/etc/my.cnf master`
[mysqld]
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock
port=3306
log_error=/usr/local/mysql/logs/error.log
server-id = 1
binlog_format = row
expire_logs_days = 30
max_binlog_size = 100M
gtid_mode = ON
enforce_gtid_consistency = ON
log-bin = /usr/local/mysql/logs/mysql-bin
log_bin_index = /usr/local/mysql/logs/mysql-bin.index
log-slave-updates = ON
[mysqld_safe]
log_error=/usr/local/mysql/logs/error.log
pid-file=/usr/local/mysql/logs/mysql.pid
[client]
socket=/usr/local/mysql/mysql.sock
/etc/init.d/mysqld start
mysql
set password=password('ZHOUjian.22');
配置从节点
`/etc/my.cnf slave1`
cat /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock
port=3306
log_error=/usr/local/mysql/logs/error.log
server-id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
log-slave-updates = ON
skip-slave-start = true
expire_logs_days = 30
max_binlog_size = 100M
read_only = ON
log-bin = /usr/local/mysql/logs/mysql-bin
log_bin_in