• MySQL MHA原理(二)

    测试MHA 的高可用

    在MySQL MHA原理(一)中,我们已经可以完整的搭建配置MHA高可用集群了,本章节来主要讲述对高可用功能的验证。 所谓高可用,就是能满足多种异常情况下的热服务,所以这里测试需要很详尽的测试用例。

    这里我首先给出测试Case及结果,有兴趣的同学可以翻看后面的具体过程:

    在MHA自动切换的情况下:

    • Case1:Master 意外宕掉,Slave正常,备选Slave正常。
    • Case2 : Master 意外宕掉,Slave落后很多binlog,备选Slave正常。
    • Case3:Master 意外宕掉,Slave正常,备选Slave落后很多binlog。
    • Case4:Master 意外宕掉,Slave复制意外停止,备选Slave正常。
    • Case5: Master 意外宕掉,Slave正常,备选Slave复制意外停止。
    • Case6:Master 意外宕掉,Slave正常,备选Slave也意外宕掉。
    • Case7:Master too many connection,Slave正常,备选Slave正常。
    • Case8:Master 正常工作,Slave (或备选Slave)意外宕掉。
    • Case9:Master 网路瞬断(1~30秒)。
    • Case10:有二次检测机制下,如果Manager通过一台Slave无法连接(另一台正常)。

    在MHA手动触发的情况下:

    • Case1:Master 意外宕掉,Slave正常,备选Slave正常。
    • Case2 : Master 意外宕掉,Slave落后很多binlog,备选Slave正常。
    • Case3:Master 意外宕掉,Slave正常,备选Slave落后很多binlog。
    • Case4:Master 意外宕掉,Slave复制意外停止,备选Slave正常。
    • Case5: Master 意外宕掉,Slave正常,备选Slave复制意外停止。
    • Case6:Master 意外宕掉,Slave正常,备选Slave也意外宕掉。
    • Case7:Master too many connection,Slave正常,备选Slave正常。
    • Case8:Master 正常工作,Slave (或备选Slave)意外宕掉。
    • Case9:Master 有大的事务或写操作在进行,Slave正常,备选Slave也正常
    • Case10:有二次检测机制下,如果Manager通过一台Slave无法连接(另一台正常)。

    如上,这些Case是我们线上的数据库可能会遇到的意外情况,不要觉得多,因为数据库宕机本身就发生在一些类似于上述的特定场景。接下来我们将一一尝试,进行上述case的验证。

    在MHA自动切换的情况下

    Case1:Master 意外宕掉,Slave正常,备选Slave正常

    • Step1:模拟Master意外宕机

    • 结果:MHA成功切换,Slave被执行新的Master并成功开始复制

    下面是manager节点上的mha切换日志,我们可以清晰的看到它的工作流程:

    如上是我省略了一些日志的内容的结果,我们发现MHA的工作内容被清晰的记录在了日志中,出了问题之后我们可以根据日志内容定位和查看。

    Case2 : Master 意外宕掉,Slave落后很多binlog,备选Slave正常

    • Step1:模拟Slave延迟,在Slave执行如下语句

    • Step2:在Mster上生成大量请求

    • Step3:模拟主库意外宕屌,并立刻开启Slave的io线程,模拟Slave延迟

    • 结果:MHA成功切换,但耗时很长,大概耗时17分钟。

    Case3:Master 意外宕掉,Slave正常,备选Slave落后很多binlog

    • Step:测试步骤与Case2类似,这里忽略不再详述。
    • 结果:MHA成功切换,但耗时很长。

    Case4:Master 意外宕掉,Slave复制意外停止,备选Slave正常

    • Step1:模拟Slave复制意外停止

    • Step2:模拟主库意外宕机

    • 结果:MHA成功切换,Slave被执行新的Master并成功开始复制

    Case5: Master 意外宕掉,Slave正常,备选Slave复制意外停止

    • Step:测试步骤与Case4类似,这里忽略不再详述。
    • 结果:MHA成功切换,备选Slave成功上位,Slave指向新的Master。

    Case6:Master 意外宕掉,Slave正常,备选Slave也意外宕掉

    • Step1: 模拟备选Slave意外宕掉

    • Step2:模拟Master意外宕掉

    • 结果:MHA切换失败,因为只剩一台Slave,也失去了切换的意义。

    Case7:Master too many connection,Slave正常,备选Slave正常

    • Step1:模拟Master 链接数过多的情况

    • 结果:MHA不会自动切换,经过确认,MHA的Manager用于检测主库是否宕机的数据库链接是长链接,在MySQL默认的配置文件下,长链接只有空闲8小时才会断开,所以Master too many connection 会导致新的链接无法建立,但是已经存在的长连接并没有受影响,所以Manager仍然可以正常检测到主库没有宕机,不会触发切换。 

    Case8:Master 正常工作,Slave (或备选Slave)意外宕掉

    • Step:测试比较简单,直接干掉Slave观察即可,这里不再详述。
    • 结果:MHA不会主动切换,Master不宕掉的话,他不会管Slave或者备选Slave的。

    Case9:Master 网路瞬断(1~30秒)

    • Step1: 模拟网路瞬断

    • Step2:等待你要测试的瞬断时长,然后再恢复Master网路

    • 结果:大概在(5~8)秒左右不会引起MHA的切换,超过这个值就会了,与你设置的 ping_interval 参数有关。

    Case10:有二次检测机制下,如果Manager通过一台Slave无法连接(另一台正常)

    • Step1: 模拟Manager无法正常连接Master

    • Step2:观察Manager状态和日志

    • 结果:MHA可以通过另外一个Slave检测到Master是OK的,所以不会触发切换

     

    在MHA手动触发的情况下

    Case1:Master 意外宕掉,Slave正常,备选Slave正常

    • Step1: 模拟Master意外宕掉

    • Step2:在Manager主动触发切换

    • 结果:成功触发MHA切换

    Case2 : Master 意外宕掉,Slave落后很多binlog,备选Slave正常

    • Step1:模拟Slave延迟,在Slave执行如下语句

    • Step2:在Mster上生成大量请求

    • Step3:模拟主库意外宕掉,并立刻开启Slave的io线程,模拟Slave延迟

    • Step4:手动触发MHA切换

    结果:MHA成功切换,但耗时很长,大概耗时17分钟。

    注意:这里你没有再配置文件的每个Server选项中指定如下参数,那么很有可能,会切换到Slave上,而不是备选Slave,这个参数会忽略各个Slave的主从延迟,而固执的切换到你指定的备选Slave上。

    check_repl_delay         =    0    

    Case3:Master 意外宕掉,Slave正常,备选Slave落后很多binlog

    • Step:测试步骤与Case2类似,这里忽略不再详述。
    • 结果:MHA成功切换,但耗时很长。

    Case4:Master 意外宕掉,Slave复制意外停止,备选Slave正常

    • Step1:模拟Slave复制意外停止

    • Step2:模拟主库意外宕机

    • 结果:MHA成功切换,Slave被执行新的Master并成功开始复制

    Case5: Master 意外宕掉,Slave正常,备选Slave复制意外停止

    • Step:测试步骤与Case4类似,这里忽略不再详述。
    • 结果:MHA成功切换,备选Slave成功上位,Slave指向新的Master。

    Case6:Master 意外宕掉,Slave正常,备选Slave也意外宕掉

    • Step1: 模拟备选Slave意外宕掉

    • Step2:模拟Master意外宕掉

    • 结果:MHA切换失败,因为只剩一台Slave,也失去了切换的意义。

    Case7:Master too many connection,Slave正常,备选Slave正常

    • Step1:模拟Master 链接数过多的情况

    • 结果:可以手动触发切换

    Case8:Master 正常工作,Slave (或备选Slave)意外宕掉

    • Step:测试比较简单,直接干掉Slave观察即可,这里不再详述。
    • 结果:MHA无法成功切换,会报出如下错误:

    Case9:Master 有大的事务或写操作在进行,Slave正常,备选Slave也正常

    • Step1: 在Master模拟大事务

    Step2:在Manager出发MHA主从切换,并观察结果

    日志如下 > 如果有大事务,MHA会一直等待,直到事务结束:

    Case10:有二次检测机制下,如果Manager通过一台Slave无法连接(另一台正常)

    • Step1: 模拟Manager无法正常连接Master

    • 结果:MHA可以手动出发切换并且成功

     

    7.1 在确认MHA正常运行之后,我直接模拟Master主库宕机,并同时查看MHA的切换日志:

    mysqladmin -uroot -pxxxxx shutdown

     

  • MySQL MHA原理(一)

    MHA的存在意义及基本特性

    我们都知道MHA是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。下面是他作为高可用框架的一些基本特性。

    参数
    故障响应时间 0 - 30s
    服务器资源的利用率 很高,MHA是独立于MySQL集群本身的,只是保证了集群的高可用。不会因为架构的原因导致某个从库单纯的只作为备份而不提供服务。
    故障切换是否安全 MHA会在切换过程中尽可能的保证数据的一致性。
    维护成本和难度 是比较成熟且受欢迎的开源高可用框架,所以文档和网上的FAQ案例也相对来说比较完善。
    二次开发特性 可以按需调整故障检测和故障响应的方式,算是比较灵活了吧
    是否会产生脑裂等现象 不会

    MHA的限制条件

    1. 目前MHA主要支持一主多从的架构

    • 要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。
    • 默认情况下,MHA是不支持3层或多层复制架构的(Master1 -> Master2 -> Slave3), MHA可以恢复Master2,但是不能恢复Slave3,因为Master2,Slave3有不同的master,为了让MHA支持以上架构,可以参考如下配置:
    • 在配置文件中,只配置两层(master1 and master2)
    • 使用 “multi_tier_slave=1” 参数,然后设置所有hosts

    2. MySQL版本必须是5.0 或者高于 5.0

    3. 使用mysqlbinlog 5.1+ 支持MySQL5.1+

    • MHA使用mysqlbinlog来应用日志到目标slave上的
    • 如果MySQL master设置的是row格式,那么MySQL必须是大于等于5.1版本,因为5.0不支持row
    • mysqlbinlog版本可以这样被检测:

    • 如果你使用的是MySQL5.1,那么mysqlbinlog必须大于等于3.3
    • 如果mysqlbinlog的版本是3.2,而mysql的版本是5.1,那么mha manager会报错,且停止monitoring

    4. log-bin必须在候选master上开启

    • 如果当前slave没有设置log-bin,那么很显然它不能成为提升为new master
    • 如果没有任何机器设置了log-bin,那么mha会报错且停止failover

    5. binlog,relay-log 主从环境必须全部一致

    • 复制过滤规则(binlog-do-db, replicate-ignore-db 等等)必须全部一致

    6. 复制用户必须在候选master上要存在

    • 切换完成后,所有slave都必须执行change master 命令。在new master上复制用户必须有(REPLICATEION SLAVE权限)

    7. 使用purge_relay_logs来定期删除relay logs

    • 默认情况下,如果SQL线程执行完relay-log,relay logs就会被自动删除。但是这些relay-logs 也许还会用来恢复其他的slave,所以你需要关闭自动删除relay-logs的purge线程,然后自己阶段性的来删除如果是你自己来删的话,必须考虑repl 延迟问题,最好让slave删除relay log不要在同一时间点,假如需要恢复,那么这个时间点所有relay logs都被删除了就不好了。

    MHA 的基本结构

    从架构上来说,MHA分为如下两大部分:

    1. Node部分

    我们知道,MHA是基于MySQL Replication环境的,在该环境中,不管是Master角色,还是Slave角色,都称为Node,是被监控管理的对象节点。

    Node服务器上需要安装MHA Node包。

    2. Manager部分

    Manager为MHA架构中的管理者,建议部署在一台独立的服务器上,当然也可部署在某个Slave上,但该Slave永远不要被选择成为新的Master,否则故障切换后的MHA架构就失去了高可用性。Manager服务器需要安装MHA Manager包,并完善一个主配置文件。

    一个Manager可管理多套MySQL Replication环境(图片摘自网上)。

    yy

    MHA安装配置

    现在我有这样一套基于3306端口的主从复制结构,需要加上MHA的高可用:

    IP地址 角色 hostname server id 类型
    10.67.250.1 Master server1 1
    10.67.250.2 slave1 + Manager server2 2 只读
    10.67.250.3 slave2 (backup) server3 3 只读
    1. 在每台MHA集群服务器上安装依赖

    2. 在每台机器上安装MHA Node软件包

    推荐使用rpm的方式安装:

    也可以选择源码安装:

    Node工具包(这些工具通常由MHA Manager的脚本触发,无需人为操作)主要包括以下几个工具:

    3. 安装MHA Manager

    推荐使用rpm的安装方式:

    也可以使用源码方式安装:

    Manager工具包主要包括以下几个工具:

    如果你采用的是源码安装,那么安装完Manager后在安装目录底下存在一个 sample/scripts 目录,里面存在了一些功能性脚本:

    4. 配置前的准备工作

    首先需要做一些配置之前的准备工作:

    4.1 两台slave服务器设置read_only

    4.2 创建监控用户,用于MHA Manager管理其他数据库node节点

    4.3 实现三台服务器之间的SSH免密码登录

    详情可参考 http://www.foreverlakers.com/tag/ssh/ 

    注: 这里要注意,如果我们配置免密码登录的用户不是root用户(比如是mhatest用户),那么需要注意以下几点:

    1. 将Manager的配置文件中指定的 manager_workdir 目录的权限修改为免密码登录认证的用户权限。比如,我们在配置文件中写到: manager_workdir = /usr/local/mha , 那么一定要确保

    chown -R mhatest:mhatest  /usr/local/mha 

    2. 将Manager的配置文件中指定的remote_workdir 目录也在对应的node节点将权限改为免密码登录认证的用户权限,比如,我们在配置文件中写道: remote_workdir = /home/data/mha, 那么一定要确保

    chown -R meatiest:mhatest /home/data/mha

    5. 配置MHA Manager

    5.1 配置MHA的Manager

    5.2 配置检查

    5.3 通过master_check_status脚本查看Manager的状态

    5.4 启动MHA Manager 即可正常运行

    5.5 再次check MHA 的Manager 是否启动成功

    6. MHA 功能分离实现

    6.1 自己监控,调用mha进行切换

    有时候,我们可能因为各种原因不想让MHA承担监控和切换的全部工作。 或许是因为不相信它,或许是因为特殊的业务逻辑,那么如果我们想自己来监控数据库的可用性,而在我们自己确定数据库故障时,用MHA作为主从切换的 工具呢 ?

    其实也很简单,在上面安装完MHA 的 Manager节点完后,会有一个masterha_master_switch 脚本,他就是MHA本身的切换脚本,所以完全可以调用他来实现手动的数据库切换。

    我们直接打开这个脚本就可以看到:

    ······省略部分·······

    # For master failover                 // 当master宕机时,可以用下面类似的形式调用

    masterha_master_switch –master_state=dead –global_conf=/etc/masterha_default.cnf –conf=/usr/local/masterha/conf/app1.cnf –dead_master_host=host1

    # For online master switch        //当master在线切换时,可以用下面类似的参数

    masterha_master_switch –master_state=alive –global_conf=/etc/masterha_default.cnf –conf=/usr/local/masterha/conf/app1.cnf

    See online reference (http://code.google.com/p/mysql-master-ha/wiki/masterha_master_switch) for details.

    =head1 DESCRIPTION

    See online reference (http://code.google.com/p/mysql-master-ha/wiki/masterha_master_switch) for details.

    6.2 自己设置主从切换时的逻辑

    如果我在故障发生时,由于业务架构的原因,不想让MHA按照既定的原则切换Master,而是按照我们自己的设定进行故障处理该怎么做呢 ?

    在上面安装完MHA 的 Manager节点完后,会有一个 master_ip_failover , 我们根据自己的需求将此脚本更新为我们想要的操作即可。 这里举个例子,如果我们的数据库复制群是建立在Atlas为proxy的基础之上的话,我们想要做到在主库宕机后,在proxy里自动下掉,或者在主库发生故障时将主库的Keepalive停掉,使得虚拟IP被切换到备库上去,我们就可以在此脚本中加上一些操作满足我们的需求。

    至此,MHA的简单原理和部署已经告一段落,后续我会专门再总结一下MHA高可用性能的测试:

    http://www.foreverlakers.com/2017/05/mysql-mha原理(二)/

    参考

    HA方案之MySQL半复制+MHA+Keepalived+Atlas+LVS

    https://yq.aliyun.com/articles/58920