MHA概览
MHA能够实现自动化的master failover和从库升级为new master,通常这一过程只需要10-30秒的停机时间.MHA最大程度保证了数据一致性,对性能零影响,易于安装,并且不需要改变现有部署情况.
MHA支持计划性在线主库切换,在短时间内(0.5-2秒)的停机时间(仅限阻塞写入),将当前运行的主机安全地更改为新主机.
MHA提供以下功能,并且可用于需要高可用性,数据完整性和近乎不间断主库维护的许多部署中.
Automated master monitoring and failover
MHA可以在现有的复制环境中监控主库状态,在检测到主库故障时执行自动切换.MHA通过从拥有最新数据的slave识别与其他slave的数据差异,获取差异relay log并应用至所有需要同步的slave来保证数据一致性.MHA可以在几秒钟内完成故障转移:9-12秒钟可以检测到主库故障,7-10秒内关闭主机以避免脑裂(可选择不power off主服务器),几秒钟内将差异中级日志应用于新主库. 总停机时间通常为10-30秒.可以在配置文件中指定候选主库.由于MHA保证了从库间的数据一致性,因此任何从库都能提升为新的主库.(主要能够连通主服务器,获取日志,理论上主和所有从库都能保证一致性)
交互式Master Failover
MHA可以手动(非自动),交互式故障切换,而不开启主库监控。
默认是开启masterha_manager监控,发现主库故障时会自动failover和选择新主库,这里说的是不开masterha_manager,手动使用masterha_master_switch切换主库.交互式是指切换过程中需要用户输入yes/no来选择是否继续执行
- 非交互式Master Failover
MHA也支持非交互式自动Master Failover而不使用MHA监控主库.这个功能对于已经配置了其他MySQL master监控软件的情景.例如,你可以使用Pacemaker(Heartbeat)来监测Master故障和vip接管,然后使用MHA做master failover和将slave提升为新主库
这里意思是不使用masterha_manager监控主库状态,而是我们已经有了其他监控软件,但是在发生故障时调用masterha_master_switch来进行处理
- 在线切换主库
当现有主库需要做硬件维护等操作时,可以使用MHA更优雅的切换主库,MHA仅阻塞0.5-2秒的写入操作即可完成主库切换.
Difficulties of Master Failover
主故障转移并不像看起来那么简单。以最经典的一主多从架构举例,当master出现故障,通常我们会选择一个和主库数据一致(或者最接近的)的从库作为新的主库,然后将其他从库change master到新主库开启复制.这个过程可能会很复杂,即便可以找到一个与原主库一致的从库做为新的主库,其他从库也未必是同步的,如果直接change master而没有先补齐数据差异,就会造成数据不一致.
MHA旨在尽可能快的完全自动化主库故障转移和恢复过程,而无需任何备机.恢复过程包括选择新主库,识别从库间relay log差异,将必要的events应用到新主库,同步其他从库并与新主库建立并启动复制.MHA通常可以在10-30秒的停机时间内进行故障转移(10秒内检测到主库故障,可选的7-10秒内关闭主库服务器以避免脑裂,几秒钟用于恢复数据至一致),具体时间取决于复制延迟度.
MHA提供自动和手动故障切换命令.自动故障切换命令“masterha_manager(MHA Manager)”由master monitoring和master failover组成。 masterha_manager会永久监控主服务器的可用性。 如果MHA Manager无法到达主服务器,则它将自动启动非交互式故障切换过程。
手动故障转移命令“masterha_master_switch”会检查master是否出现了故障(dead)。 如果master dead,masterha_master_switch将其中一个从库作为新的主库(您可以选择一个首选主机),并启动恢复和故障切换。 在内部,它做的更多,但是您只执行一个命令,而无需自己执行复杂的恢复和故障转移操作。
MHA架构
When a master crashes, MHA recovers rest slaves as below.
从库上的relay log中,主库的binary log positions写在end_log_pos部分(example).通过比较从库relay log中最后的end_log_pos,我们可以确定哪些relay log events没有被发送到从库.MHA通过这个机制恢复从库.In addition to basic algorithms covered in the slides at the MySQL Conf 2011, MHA does some optimizations and enhancements, such as generating differential relay logs very quickly (indenpendent from relay log file size), making recovery work with row based formats, etc.
MHA组件
MHA由MHA Manager和MHA Node组成.
Manager可以管理多个 复制集群
- masterha_manager:提供实现自动故障检测和故障转移的命令
- masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_manger 启动MHA
masterha_check_status 检测当前MHA运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息Node部署在所有节点
- save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog 去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
MHA Manager具有如监控MySQL master和控制故障转移等程序
MHA Node具有一些帮助主库进行故障转移的脚本,例如:解析MySQL binary/relay log;识别relay log位置,进而判断哪些event需要应用到其他从库;应用events到目标从库等. MHA Node运行在每个MySQL服务器上
当MHA Manager进行故障切换时,MHA Manager通过SSH连接MHA节点,并在需要时执行MHA节点命令.
自定义扩展
MHA有几个用户可以自行扩展的脚本.例如,MHA可以调用任何自定义脚本切换VIP.
- secondary_check_script:用于检查来自多个网络路由的主机可用性
- master_ip_failover_script:用于更新应用程序使用的主机的IP地址(vip)
- shutdown_script:用于强制关闭主服务器
- report_script:发送报告(邮件)
- init_conf_load_script:用于加载初始配置参数
- master_ip_online_change_script:更新主IP地址(vip)。 当通过masterha_master_switch执行在线主库切换时,需要此脚本来切换vip
secondary_check_script
通常来说,非常推荐使用两个或更多的网络线路检测MySQL master服务器的可用性。默认情况下,MHA Manager只是用单个线路检测:从Manager到Master。但是这个并不推荐。MHA通过调用一个额外的脚本(通过secondary_check_script参数指定),实际上可以有两个或更多的检查线路。配置示例:
secondary_check_script =masterha_secondary_check -s remote_host1 -s remote_host2
masterha_secondary_check在MHA Manager包中已经包含。内置的masterha_secondary_check 脚本在大多数情况下都是比较好的,这里也可以调用其他任意脚本。
在上述示例中,MHA Manager通过Manager-(A)->remote_host1-(B)->master_host和 Manager-(A)->remote_host2-(B)->master_host检测MySQL master服务器。如果在两个线路中都会出现:connection A是成功的,但是B是不成功的,则masterha_secondary_check会退出(返回0),并且MHAManager决定MySQL master真的挂掉了,然后会进行failover。如果A是不成功的,masterha_secondary_check会退出(返回2),并且MHAManager猜测发生网络问题,不会进行failover。如果B是成功的,masterha_secondary_check会退出(返回3),并且MHAManager 推断MySQL master是存活的,不会进行failover。
一般来讲,remote_host1 和 remote_host2 应该位于不同的网段(从MHA Manager和MySQL服务器)。
MHA 调用secondary_check_script参数定义的脚本,自动传一下参数(所以不需要再配置文件中设置以下参数)。 masterha_secondary_check 在许多情形下是适宜的,但是如果你需要更多功能可以自己写一些网络监测脚本。
- –user=(远程hosts的SSH用户名。ssh_user 参数的值会被传入)
- –master_host=(master的hostname)
- –master_ip=(master的ip 地址)
- –master_port=(master的端口号)
内置的masterha_secondary_check 脚本依赖于IO::Socket::INETPerl包,从Perl v5.6.0开始已经默认包含。masterha_secondary_check 脚本也是通过SSH连接到远程服务器,所以也需要SSH公共密钥验证。还有,masterha_secondary_check 脚本尝试从远程服务器(set by -s)到MySQLmaster建立TCP连接。my.cnf中设置的max_connections参数不会影响,如果TCP连接成功,master上的aborted_connects值会加1。
master_ip_failover_script
在常见的HA环境中,许多情形下会在master上分配一个虚拟IP地址。如果master挂掉,HA软件(比如:Pacemaker)会接管虚拟IP到备机上。
另一个常见的处理方式是创建一个全局性的目录数据库,该数据库包含应用名称和读写IP地址之间的映射(i.e. {app1_master1, 192.168.0.1}, {app_master2, 192.168.0.2}, …)。这种情形下,在当前master挂掉之后需要更新目录数据库。
两者方式各有优势和劣势。MHA不强制使用其中一种方式,允许用户使用任何一种IP地址故障切换的解决办法,master_ip_failover_script参数被用于解决这个。 换句话说,需要编写一个脚本使应用透明的连接到new master,必须定义在master_ip_failover_script 参数中。实例如下:
1 | master_ip_failover_script= /usr/local/sample/bin/master_ip_failover |
示例及保本位于(MHA Manager包)/samples/scripts/master_ip_failover。 示例脚本在MHA Managertarball和GitHup分支中包含。
MHA Manager 调用master_ip_failover_script 三次。第一次在进入master监控之前(脚本有效性检查),第二次是在调用shutdown_script脚本之前,第三次是在应用差异relay log到new master之后。MHA Manager 传入以下参数(不需要在配置文件中配置)。
- Checking 阶段
- –command=status
- –ssh_user=(当前master的ssh username)
- –orig_master_host=(当前master 的 hostname)
- –orig_master_ip=(当前 master的 ip地址)
- –orig_master_port=(当前master的端口号)
- 当前master shutdown阶段
- –command=stop 或 stopssh
- –ssh_user=(dead master的 ssh username,如果可以通过SSH访问)
- –orig_master_host=(current(dead) master的 hostname)
- –orig_master_ip=(current(dead) master的 ip 地址)
- –orig_master_port=(current(dead) master的 端口号)
- New master 激活阶段
- –command=start
- –ssh_user=(new master的 ssh username)
- –orig_master_host=(dead master的 hostname)
- –orig_master_ip=(dead master的 ip 地址)
- –orig_master_port=(dead master的端口号)
- –new_master_host=(new master的 hostname)
- –new_master_ip=(new master的 ip 地址)
- –new_master_port(new master的端口号)
- –new_master_user=(new master的用户)
- –new_master_password(new master的密码)
如果在master上使用了一个共享的虚拟IP地址,只要在之后shutdown_script中关掉了机器,在shutdown阶段可能不需要做任何事。在newmaster激活阶段,可以在new master上指定虚拟IP。
如果使用了目录数据库的方式,在master shutdown阶段需要delete或者update dead master的记录。在new master激活阶段,可以insert/update new master的记录。还有,可以做任何你需要做的事,使得应用可以写入new master。比如,SET GLOBAL read_only=0,创建拥有write权限的数据库用户,等等。
MHA Manager 检查该脚本退出的code(return code)。如果脚本返回的code为0或者10,MHA Manager 继续操作。 如果脚本返回的code不是0或者10,MHA Manager终止,不会继续故障切换。参数默认为空。
report_script
failover完成或者因为错误结束的时候可能需要发送报告(i.e. e-mail)。report_script 用于这个目的。MHA Manager传入以下参数。
- –orig_master_host=(dead master的 hostname)
- –new_master_host=(new master的 hostname)
- –new_slave_hosts=(new slaves 的 hostnames,通过逗号分隔)
- –subject=(mail subject)
- –body=(body)
参数默认为空。
示例脚本位于(MHA Manager 包)/samples/scripts/send_report。示例脚本在MHA Managertarball 和 GitHub分支中包含。
init_conf_load_script
当不想在配置文件中设置纯文本(i.e. password和repl_password)的时候可以使用该脚本。通过从该脚本返回 “name=value” 对,可以覆盖全局配置文件的参数。示例如下。
1 | #!/usr/bin/perl |
master_ip_online_change_script
类似于master_ip_failover_script 参数,但是该参数不是用于master故障切换的命令,用于master在线切换命令(masterha_master_switch–master_state=alive)。传入以下参数。
- Current master阻塞写入阶段
- –command=stop 或 stopssh
- –orig_master_host=(current master的 hostname)
- –orig_master_ip=(current master的 ip 地址)
- –orig_master_port=(current master的端口号)
- –orig_master_user=(current master的用户)
- –orig_master_password=(current master的密码)
- –orig_master_ssh_user=(从0.56支持, current master的 ssh user)
- –orig_master_is_new_slave=(从0.56支持, 表示原来的master是否会成为新的slave)
- New master 赋write权限阶段
- –command=start
- –orig_master_host=(orig master的hostname)
- –orig_master_ip=(orig master的 ip 地址)
- –orig_master_port=(orig master的端口号)
- –new_master_host=(new master的 hostname)
- –new_master_ip=(new master的ip 地址)
- –new_master_port(new master的端口号)
- –new_master_user=(new master的用户)
- –new_master_password=(new master的密码)
- –new_master_ssh_user=(从0.56支持, new master的 ssh user)
当前master阻塞写阶段,MHA 在当前master上执行 FLUSH TABLES WITH READ LOCK 。在new master赋wirte权限阶段,可以做和master_ip_failover_script一样的事情。比如,创建有权限的用户,执行SET GLOBAL read_only=0,更新目录数据库,等等。如果脚本返回的code不是0或10,则MHA Manager 会终止,并且不会继续master切换。
默认参数为空。
示例脚本位于(MHA Manager包)/samples/scripts/master_ip_online_change。
典型用例
一主多从
1 | M(RW) M(RW), promoted from S1 |
最常见的复制场景
一主多从,其中一个从库在异地
1 | M(RW) M(RW), promoted from S1 |
通常我们可能会需要在异地数据中心搭建一个从库,但当主库宕机时,我们并不希望该从库被提升为新主库,而是希望一个与原主库同机房的从库作为新主库.可以通过在配置文件中向Sr区块添加no_master=1参数来从候选名单中移除Sr
一主多从,一个候选主库
1 | M(RW)-----S0(R,candidate_master=1) M(RW), promoted from S0 |
有时我们想指定一个特定的从库作为新主库.可以通过在配置文件中向希望的从库区块下添加candidate_master=1来实现这一需求
双主
1 | M(RW)<--->M2(R,candidate_master=1) M(RW), promoted from M2 |
双主,M读写,M2只读, M下挂两个从库. 切换后M2作为新主 S1,S2 change master到M2.
只要M2是只读的,MHA就支持多主配置
MHA Manager supports multi-master configurations as long as all non-primary masters (M2 in this figure) are read-only.
三层复制
1 | M(RW) M(RW), promoted from S1 |
M主库RW模式,S1 S2为本地只读从库,Sr为远程只读从库,Sr2为Sr的从库.这种结构下MHA仍然可以支持master failover.在配置文件配置master和所有二层的从库(在这个例子添加M,S1,S2和Sr到配置文件,但是不要添加Sr2到配置文件中).如果有master宕机,MHA自动提升二层从库(S1或S3或Sr.取决于优先级)为新主库,并恢复其他二层从库. 第三次的从库Sr2不受MHA管理,不过只要Sr2的主库可用,Sr2仍然可以继续复制.
如果Sr宕机,Sr2将不能继续复制,因为Sr2的主库是Sr.MHA不能回复Sr2
This is where support for global transaction id is desired. Hopefully this is less serious than master crash.每台明白,意思是这就是为什么需要GTID?有了GTID Sr2就可以change master到新主了吧
三层复制,双主
1 | M1(host1,RW) <-----------------> M2(host2,read-only) |
MHA通用支持这种结构.在这个结构下host5是一个第三层的slave,所以MHA不能管理host5(MHA does not execute CHANGE MASTER on host5 when the primary master host1 fails).当host1 dow,host2将会成为新主库,所以host5可以keep replication from host2 without doing anything. 下面是配置文件示例.
1 | [server default] |