MHA

MHA 介绍 ? MHA是一位日本MySQL大牛用Perl写的一套MySQL故障切换方案,来保证数据库系统的高可用.在宕机的时间内(1030秒内),完成故障切换,部署MHA,可避免主从一致性问题,节约购买新服务器的费用,不影响服务器性能,易安装,不改变现有部署。MHA还支持在线切换,从当前运行master切换到一个新的master上面,只需要很短的时间(0.52秒内),切换时仅仅阻塞写操作,并不影响读操作,便于主机硬件维护。在有高可用,数据一致性要求的系统上,MHA 提供了强大的功能,几乎无间断的满足维护需要。
优点
1 主库自动监控和故障转移 ? 在当前已存在的主从复制环境中,MHA可以监控主库故障,并自动转移故障。即使有一些从库没有接收到新的relay log events,MHA也会从接收过的其他从库中自动识别有差异的relay log events,并在没接收到的从库上进行数据的前滚,以此来保障主从数据的一致性。
? MHA可达到秒级别故障转移(9~12秒监测到主库故障,任选7秒钟关闭主库电源主机避免脑裂,接下来对数据不全的从库进行数据的前滚(通过其他完整从库的中继日志relay log)),最后建立新的主库,总停机时间在(total downtime)10~30秒)。另外,在配置文件里可以配置一个从库优先成为主库,因为MHA修复了从库之间的一致性,dba就不用去处理一致性问题。当建立新的主库之后,并行恢复其他从库。即使有成千上万的从库,也不会影响恢复主库时间,从库也很快完成数据同步。
? 例子:DeNA公司在150+主从环境中使用MHA。其中一个master崩溃,MHA在4秒完成故障转移,这是主动/被动集群解决方案无法完成的。
2 互动(手动)master故障转移 ? MHA可以用来只做故障转移,即不监测主库状态,只作为故障转移的交互。
3 非交互式故障转移 ? MHA也提供非交互式的故障转移(不监测主库状态,自动故障转移)。这个特性很有用,特别是你已经安装了其他软件监控主库。比如,用Pacemaker(Heartbeat)监测主库故障和vip接管,用MHA进行故障转移和从库提升。
4 在线切换主库到不同主机 ? 在很多情况下,有必要将主库转移到其他主机上(如替换raid控制器,提升主库机器硬件等等)。这并不是主库崩溃,而是计划维护必须去做的。计划维护会导致downtime,所以必须尽可能快的恢复。快速的主库切换和优雅的阻塞写操作是必需的,MHA提供了这种方式。优雅的主库切换, 0.52秒内阻塞写操作。在很多情况下0.52秒的downtime是可以接受的,并且不影响计划维护窗口。这意味着当需要更换更快机器,升级高版本时,dba可以很容易采取动作。
5 master 崩溃不会导致主从数据不一致性

当master 崩溃后,MHA自动识别从库间relay log events的不同,然后应用于不同的从库上,最终所有从库都同步。结合通过半同步一起使用,几乎没有任何数据丢失。

6 MHA部署不影响当前环境设置 ? MHA最重要的一个设计理念就是尽可能使用简单。其他高可用方案需要改mysql部署设置,MHA不会让dba做这些部署配置,同步和半同步环境都可以用。启动/停止/升级/降级/安装/卸载 MHA都不用改变(如启动/停止)mysql主从环境。
? 当你需要升级MHA到新版本时,不需要停止mysql,仅仅更新HMA版本,然后重新启动MHAmanger即可。有些高可用方案要求特定的mysql版本(如mysql cluster,mysql with global transaction id 等),而且你可能不想仅仅为了MasterHA而迁移应用。很多情况下,公司已经部署了许多传统的mysql应用,开发或dba不想花太多时间迁移到不同的存储引擎或新的特性上。
7 不增加服务器费用 ? MHA 包含MHA Manager和MHA node。MHA node运行在每台mysql服务器上,Manager可以单独部署一台机器,可监控100+以上数量的数据库,总服务器数量不会有太大增加。需要注意的是Manager也可以运行在其中一台从库上。
8 性能无影响 ? 当监控主库时,MHA只是每几秒钟(默认3秒)发送ping包,不发送大的查询。主从复制性能不受影响。
9 适用任何存储引擎 ? Mysql不仅仅适用于事务安全的innodb引擎,在主从中适用的引擎,MHA都可以适用。即使使用遗留环境的myisam引擎,不进行迁移,也可以用MHA。
架构 在架构上来说,MHA分为两类:
1)Node
? MHA是基于MySQL 主从复制环境的,在该环境中,不管是Master角色,还是Slave角色,都称为Node,是被监控管理的对象节点。Node服务器上需要安装MHA Node包。
2)Manager
? Manager为MHA架构中的管理者,建议部署在一台独立的服务器上,当然也可部署在某个Slave上,但该Slave永远不要被选择成为新的Master,否则故障切换后的MHA架构就失去了高可用性。Manager服务器需要安装MHA Manager包,并完善一个主配置文件。一个Manager可管理多套MySQL 主从复制环境。
原理 ? 相较于其它HA软件,MHA的目的在于维持MySQL 主从复制中主库的高可用性,其最大特点是可以修复多个从库之间的差异日志,最终使所有从库保持数据一致,然后从中选择一个充当新的主库,并将其它从库指向它。
基本工作流程大致如下:
(1)Manager定期监控主库
? Manager会定时监控主库状态,监控时间间隔由参数ping_interval决定,缺省为3秒钟一次;可利用其自身的监控功能,也可调用第三方软件来监控;MHA自身提供了两种监控方式:SELECT(执行SELECT 1)和CONNECT(创建连接/断开连接),由参数ping_type决定,缺省为SELECT方式。
(2)主库故障发生
? Manager会调用SSH脚本对所有Node执行一次检查,包括如下几个方面:
――MySQL实例是否可以连接;
――主库服务器是否可以SSH连通;
――检查SQL Thread的状态;
――检查哪些从库死掉了,哪些从库是活动的,以及活动的从库实例数据是否完整;
――检查从库实例的配置及复制过滤规则;
――最后退出监控脚本并返回相应的状态代码。
(3)主库故障切换
? 包括如下几个阶段:
3.1 Configuration Check Phase(检查配置) ? 在这个阶段,若某个从库实例的SQL Thread停止了,则会自动启动它;并再次确认活动的Servers及Slaves。
3.2 Dead Master Shutdown Phase(关闭死主) ? 在这个阶段,首先调用master_ip_failover_script,若HA是基于VIP实现的,则关闭VIP,若是基于目录数据库实现的,则修改映射记录。然后调用shutdown_script强制关闭主机,以避免服务重启时,发生脑裂。
3.3 Master Recovery Phase(确立新主库) ? 包括如下3个阶段:
3.3.1 Getting Latest Slaves Phase(检查从库) ? 检查各个从库,获取最近的和最旧的binary log和position,并检查各个从库成为主库的优先级,优先级取决于candidate_master、no_master、[server_xxx]顺序、binary log差异量等因素。
3.3.2 Saving Dead Master’s Binlog Phase(保存死主日志) ? 若死主所在服务器依然可以通过SSH连通,则提取出死主的binary log,提取日志的起点就是上一步获取的最新的binary log和position,直到最后一条事务日志,并在死主本地的工作目录(由参数remote_workdir决定)中创建文件保存这些提取到的日志,然后将该文件拷贝到Manager服务器的工作目录下(由参数manager_workdir决定)。当然,若死主所在服务器无法再连接,也就不存在差异的binary log了。另外,MHA还要对各个从库节点进行健康检查,主要是SSH连通性检查。
3.3.3 Determining New Master Phase(建立新主) ? 接下来调用apply_diff_relay_logs恢复从库间的差异日志,这个差异日志指的是各个从库之间的relay log差异。恢复完成后,所有的从库数据是一致的,此时就可以根据优先级选择新主了。
3.3.4 New Master Diff Log Generation Phase(新主生成差异日志) ? 这一步是生成已死主和新主之间的差异日志,即将3.3.2中从已死主上提取出的binary log拷贝到新主的工作目录中(remote_workdir)。
3.3.5 Master Log Apply Phase(新主日志复制) ? 将上一步拷贝的差异日志恢复到新主上,若发生错误,也可手动恢复。然后获取新主的binlog name和position,让其它从库从这个新的binlog name和position开始复制。最后会开启新主的写权限,也就是将read_only参数设置为0。
3.4 Slaves Recovery Phase(确立新主从关系) ? 包括如下2个阶段:
3.4.1 Starting Parallel Slave Diff Log Generation Phase ? 生成新主与新从库之间的差异日志,并将该日志拷贝到各从库的工作目录下。
3.4.2 Starting Parallel Slave Log Apply Phase ? 在各个从库上应用这部分差异日志,然后通过CHANGE MASTER TO命令将这些从库指向新主,最后开始主从复制(start slave)。
3.5 New master cleanup phase(新主洗白) ? 重置新主的slave info,即取消原来的从库信息。至此整个主库故障切换过程完成。
环境搭建 环境
系统 MySQL MHA
Linux version 3.10.0-862.el7.x86_64 mysql-5.7.20 mha4mysql-manager-0.57-0.el7.noarch
mha4mysql-node-0.57-0.el7.noarch
Mysql下载:https://downloads.mysql.com/archives/community
MHA下载:http://code.google.com/p/mysql-master-ha/downloads/list
四台机子
主机名 IP 作用
manager 10.2.2.100 MHA管理节点
node1 10.2.2.101 主库
node2 10.2.2.102 从库1
node3 10.2.2.103 从库2
[root@master ~]# cat /etc/hosts 127.0.0.1localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1localhost localhost.localdomain localhost6 localhost6.localdomain6 100.2.2.100 manager 100.2.2.101 master 100.2.2.102 slave1 100.2.2.103 slave2

? 修改主机名和hosts文件,关闭防火墙、selinux,关闭NetworkManager服务不赘述;yum需要配置阿里云、epel、和本地源。
epel源下载:http://dl.fedoraproject.org/pub/epel
? 在该网站下载自己需要的epel源rpm包
[root@master ~]# mount -o ro /dev/sr0 /mnt/ [root@master ~]# rpm -ivh epel-release-latest-7.noarch.rpm [root@master ~]# cat /etc/yum.repos.d/server.repo [local] name=local yum baseurl=file:///mnt enabled=1 gpgcheck=0 [aliyun] name=this is aliyun yum baseurl=http://mirrors.aliyun.com/centos/7/os/x86_64/ enabled=1 gpgcheck=0

? MHA是采用perl语言编写的一个脚本管理工具,所以需要安装一系列perl依赖包:
yum -y install perl-DBD-MySQL \ perl-Config-Tiny \ perl-Time-HiRes \ perl-Mail-Sender \ perl-Mail-Sendmail \ perl-MIME-Base32 \ perl-MIME-Charset \ perl-MIME-EncWords \ perl-Params-Classify \ perl-Params-Validate.x86_64 \ perl-Log-Dispatch \ perl-Parallel-ForkManageryum -y install net-tools

【MHA】? 依赖包成功安装后,会在/usr/bin目录下生成如下一系列命令工具:
/usr/bin/masterha_check_repl/usr/bin/masterha_conf_host/usr/bin/masterha_master_switch/usr/bin/masterha_check_ssh/usr/bin/masterha_manager/usr/bin/masterha_secondary_check/usr/bin/masterha_check_status/usr/bin/masterha_master_monitor

? 至此,这四台机子的基本环境搭建完成。
数据库主从搭建 ? MHA基于数据库主从环境,这里用一主二从来模拟环境。
? 安装数据库,前面讲过,不赘述,进行三台机子的主从搭建,后面会讲,不赘述。
我master,slave1,slave2数据库的环境如下: install_dir:/mysql data_dir:/mysql/data port:3306 socket:/tmp/mysql.sock

MHA软件安装 不同节点安装软件
? 说明:在所有节点安装 mha-node 软件包,在 mha 管理端再安装 mha-manager 软件包
[root@manager ~]# yum -y install mha4mysql-node-0.57-0.el7.noarch.rpm [root@manager ~]# yum -y install mha4mysql-manager-0.57-0.el7.noarch.rpm [root@master ~]# yum –y install mha4mysql-node-0.57-0.el7.noarch.rpm [root@slave1 ~]# yum -y install mha4mysql-node-0.57-0.el7.noarch.rpm [root@slave2 ~]# yum –y install mha4mysql-node-0.57-0.el7.noarch.rpm

配置ssh互信
说明:在生产环境中几乎都是禁止root远程登陆服务器的,所以ssh免密码登陆要在mysql用户下进行配置,这是处于安全角度考虑出发。
master端: [mysql@master ~]$ ssh-keygen -P "" -f ~/.ssh/id_rsa [mysql@master ~]$ rm -rf .ssh/*slave1和slave2端: [mysql@slave1 ~]$ ssh-keygen -P "" -f ~/.ssh/id_rsa [mysql@slave1 ~]$ rm -rf .ssh/*[mysql@slave2 ~]$ ssh-keygen -P "" -f ~/.ssh/id_rsa [mysql@slave2 ~]$ rm -rf .ssh/*mha-mgr端: [root@manager ~]# su - mysql [mysql@manager ~]$ ssh-keygen -P "" -f ~/.ssh/id_rsa [mysql@manager ~]$ cd .ssh/ [mysql@manager .ssh]$ ls id_rsaid_rsa.pub [mysql@manager .ssh]$ mv id_rsa.pub authorized_keys [mysql@manager .ssh]$ for i in 101 102 103; do scp * 10.2.2.$i:~/.ssh/; done测试免密登录: [mysql@manager .ssh]$ ssh 10.2.2.101 [mysql@manager .ssh]$ ssh 10.2.2.102 [mysql@manager .ssh]$ ssh 10.2.2.103ssh-keygen -P "" -f ~/.ssh/id_rsa for i in 101 100 103; do ssh-copy-id -i 10.2.2.$i; done

配置mysql用户的sudo权限
  • 配置mysql用户执行sudo命令权限
    [root@master ~]# vim /etc/sudoers.d/mysql#User_Alias表示具有sudo权限的用户列表; Host_Alias表示主机的列表User_Alias MYSQL_USERS = mysql#Runas_Alias表示用户以什么身份登录Runas_Alias MYSQL_RUNAS = root#Cmnd_Alias表示允许执行命令的列表Cmnd_Alias MYSQL_CMNDS = /sbin/ifconfig,/sbin/arpingMYSQL_USERS ALL = (MYSQL_RUNAS) NOPASSWD: MYSQL_CMNDS[root@master ~]# for i in 102 103; do scp /etc/sudoers.d/mysql 10.2.2.$i:/etc/sudoers.d/

  • 测试mysql用户是否可以挂载VIP
    [mysql@master ~]$ sudo /sbin/ifconfig ens33:1 10.2.2.200 broadcast 10.2.2.255 netmask 255.255.255.0[mysql@master ~]$ sudo /sbin/arping -f -q -c 5 -w 5 -I ens33 -s 10.2.2.200 -U 10.2.2.101[mysql@master ~]$ ifconfig 补充:arping:用来向局域网内的其它主机发送ARP请求的指令,可以用来测试局域网内的某个IP是否已被使用。Usage: arping -fqbDUAV -w timeout [-s source] destination-f:收到第一个响应包后退出。-q:quite模式,不显示输出。 -c:发送指定的count个ARP REQUEST包后停止。如果指定了-w参数,则会等待相同数量的ARP REPLY包,直到超时为止。-w:指定一个超时时间,单位为秒,arping在到达指定时间后退出,无论期间发送或接收了多少包。在这种情况下,arping在发送完指定的count(-c)个包后并不会停止,而是等待到超时或发送的count个包都进行了回应后才会退出。 -I:指定设备名,用来发送ARP REQUEST包的网络设备的名称。-D:重复地址探测模式,用来检测有没有IP地址冲突,如果没有IP冲突则返回0。 -s:设置发送ARP包的IP资源地址-U:无理由的(强制的)ARP模式去更新别的主机上的ARP CACHE列表中的本机的信息,不需要响应。-h:显示帮助页。

创建mha相关配置文件
  • 创建 mha 相关的工作目录
[root@manager ~]# mkdir /etc/mha/ && mkdir -p /data/mha/masterha/app1 && chown -R mysql. /data/mha

? 创建mha局部配置文件
[root@manager ~]# cat /etc/mha/app1.conf [server default] # 设置监控用户和密码 user=mha password=Ct%123456 # 设置复制环境中的复制用户和密码 repl_user=reply repl_password=Ct%123456 # 设置ssh的登录用户名 ssh_user=mysql # 设置监控主库,发送ping包的时间间隔,默认是 3 秒,尝试三次没有回应的时候自动进行failover ping_interval=3 # 设置mgr的工作目录 manager_workdir=/data/mha/masterha/app1 # 设置mysql master 保存 binlog 的目录,以便 MHA 可以找到 master 的二进制日志 master_binlog_dir=/mysql/data # 设置 master 的 pid 文件 master_pid_file=/mysql/data/master.pid # 设置 mysql master 在发生切换时保存 binlog 的目录(在mysql master上创建这个目录) remote_workdir=/data/mysql/mha # 设置 mgr 日志文件 manager_log=/data/mha/masterha/app1/app1-3306.log # MHA 到 master 的监控之间出现问题,MHA Manager 将会尝试从slave1和slave2登录到master上 secondary_check_script=/usr/bin/masterha_secondary_check -s 10.2.2.102 -s 10.2.2.103 --user=mysql --port=22 --master_host=10.2.2.101 --master_port=3306 # 设置自动 failover 时候的切换脚本 master_ip_failover_script="/etc/mha/master_ip_failover.sh 10.2.2.200 1" # 设置手动切换时候的切换脚本 #master_ip_online_change_script="/etc/mha/master_ip_online_change.sh 10.2.2.200 1" # 设置故障发生后关闭故障主机脚本 # shutdown_script="/etc/mha/power_manager" [server1] hostname=10.2.2.101 port= 3306 candidate_master=1 [server2] hostname=10.2.2.102 port= 3306 candidate_master=1 [server3] hostname=10.2.2.103 port= 3306 no_master=1

上传脚本
[root@manager ~]# ls /etc/mha/ app1.confmaster_ip_failover.shmaster_ip_online_change.shpower_manager 注意:脚本内容中要修改网卡名字 my $vip= shift; my $interface = 'ens33'; my $key = shift; [root@manager ~]# chmod 755 /etc/mha/master_ip_* && chmod 755 /etc/mha/power_manager

检查ssh互信和集群状态 检查互信
[mysql@manager ~]$ masterha_check_ssh --conf=/etc/mha/app1.conf

检查集群状态
[mysql@manager ~]$ masterha_check_repl --conf=/etc/mha/app1.conf

检查MHA-Mgr状态
[mysql@manager ~]$ masterha_check_status --conf=/etc/mha/app1.conf app1 is stopped(2:NOT_RUNNING). 开启MHA Manager监控: [mysql@manager ~]$ nohup masterha_manager --conf=/etc/mha/app1.conf --remove_dead_master_conf --ignore_last_failover & 再次查看监控状态: [mysql@manager ~]$ masterha_check_status --conf=/etc/mha/app1.conf注意: 1. 如果正常,会显示”PING_OK ”,否则会显示”NOT_RUNNING ”,说明 MHA监控没有开启 2. 使用mysql用户启动监控,否则会报权限拒绝 3. 手动停止监控命令:masterha_stop --conf=/etc/mha/app1.conf

自动Failover测试 安装测试工具
[root@master ~]# yum -y install sysbench -y

创建测试数据
mysql> create database autotest charset utf8; Query OK, 1 row affected (0.17 sec)mysql> grant all on *.* to 'mha'@'localhost' identified by 'Ct%123456'; Query OK, 0 rows affected (0.14 sec)mysql> flush privileges; Query OK, 0 rows affected (0.11 sec)mysql> exit Bye[root@master ~]# sysbench /usr/share/sysbench/oltp_read_only.lua \ --mysql-host=10.2.2.101--mysql-port=3306 --mysql-user=mha \ --mysql-password=123--mysql-socket=/tmp/mysql.sock \ --mysql-db=autotest--db-driver=mysql--tables=1 \ --table-size=100000 --report-interval=10 --threads=128 --time=120 prepare

模拟故障
[root@master ~]# service mysql stop

查看切换过程
[root@mha-mgr ~]# tail -f /data/mha/masterha/app1/app1-3306.log

    推荐阅读