• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

MySQL基于MHA高可用部署篇(Binlog模式)

MySQL 彭东稳 7年前 (2017-02-20) 22159次浏览 已收录 2个评论

一、部署MHA前提要求(必须满足)

1. SSH公钥认证

基本上MHA manager,MNA node,以及二次检测的节点,都需要互相信任。如果slave比较多,实例比较多,最好提高下 /etc/ssh/sshd_config MaxStartups 的值(默认是10)。

2. 操作系统

仅在Linux上测试过。

3. 单写master和多slave或者只读master

打从一开始,MHA就是为了解决数据一致性而出生,所以,最好是多个slave。如果你只有一个slave,根本就碰不到数据一致性问题,也就不需要mha了

如果是一个slave,用半同步复制也能解决。从mha 0.52开始,就支持多master的复制架构了,下面列举了多master环境下注意点:

  • 多master,但是只允许单点写入。
  • 默认情况下,只支持2层复制架构。

4. 三层或者多层复制环境

默认情况下,MHA是不支持3层或多层复制架构的(Master1 -> Master2 -> Slave3)。MHA可以恢复Master2,但是不能恢复Slave3,因为Master2,Slave3有不同的master。为了让MHA支持以上架构,可以参考如下配置:

  • 在配置文件中,只配置两层(master1 and master2)。
  • 使用 “multi_tier_slave=1” 参数,然后设置所有hosts。

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

  • MySQL版本必须大于等于5.0。
  • 尽量使用高版本的MySQL。

6. 使用mysqlbinlog 5.1+ 支持MySQL 5.1+

  • MHA使用mysqlbinlog来应用日志到目标slave上的。
  • 如果MySQL master设置的是row格式,那么MySQL必须是大于等于5.1版本,因为5.0不支持row。
  • mysqlbinlog版本可以这样被检测,mysqlbinlog –version。
  • 如果你使用的是MySQL5.1,那么mysqlbinlog必须大于等于3.3。
  • 如果mysqlbinlog的版本是3.2,而mysql的版本是5.1,那么mha manager会报错,且停止monitoring。

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

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

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

  • 对于主从两边的配置最好一模一样(不需要配置中设置read_only),主要是主库要有从库相关的复制参数配置。
  • 复制过滤规则(binlog-do-db, replicate-ignore-db等等)必须全部一致,不然检查到会退出。

9. 主库复制用户和业务用户必须在候选master上要存在

  • 切换完成后,所有业务连接到新的主库,所以旧的主库用到的业务账号也必须在新主库有一份,不然就有大问题。
  • 切换完成后,所有slave都必须执行change master命令。在new master上复制用户必须有(REPLICATEION SLAVE权限)。

10. 使用purge_relay_logs来定期删除relay logs(两个节点则不必关心此条)

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

11. 不要在SBR的环境中使用load data infile

不管是SBR,还是RBR,最好不要使用load data。

二、部署MHA

1. 环境准备

接下来部署MHA,具体的搭建环境如下(所有操作系统均为centos 7.2 64bit,不是必须,mysql02和mysql03是mysql01的从,复制环境搭建后面会简单演示,但是相关的安全复制不会详细说明,需要的童鞋请参考前面的文章,MySQL Replication需要注意的问题):

角色 IP地址 主机名 server_id 类型
mha manager 10.99.73.7 mha mha
mysql master 10.99.73.9 mysql01 100 写入
mysql slave 10.99.73.10 mysql02 200 读(candidate_master)
mysql slave 10.99.73.11 mysql03 300 读(no_master)

其中master对外提供写服务,备选master(实际的slave,主机名mysql02)提供读服务,slave也提供相关的读服务,一旦master宕机,将会把备选master提升为新的master,slave指向新的master。

关闭各个主机iptables加selinux

各个主机配置hosts

各个主机配置SSH互信,基本上MHA manager,MHA node,以及二次检测的节点,都需要互相信任。如下示例:

2. 安装MHA Node

1)在所有节点安装MHA node所需的perl模块,需要epel源,使用yum安装。

2)在所有的节点安装mha node

安装完成后会在/usr/local/bin目录下生成以下脚本文件:

关于上面脚本的功能,上面已经介绍过了,这里不再重复了。

3. 安装MHA Manager

MHA Manager中主要包括了几个管理员的命令行工具,例如master_manger,master_master_switch等。MHA Manger也依赖于perl模块,具体如下:

1)安装MHA Node软件包之前需要安装依赖。我这里使用yum完成,没有epel源的可以使用上面提到的脚本(epel源安装也简单)。注意:在MHA Manager的主机也是需要安装MHA Node。

安装MHA Node软件包,和上面的方法一样,如下:

2)安装MHA Manager,首先安装MHA Manger依赖的perl模块(我这里使用yum安装):

安装MHA Manager软件包:

安装完成后会在/usr/local/bin目录下面生成以下脚本文件,前面已经说过这些脚本的作用,这里不再重复。

复制相关脚本到/usr/local/bin目录(软件包解压缩后就有了,不是必须,因为这些脚本不完整,需要自己修改,这是软件开发着留给我们自己发挥的,如果开启下面的任何一个脚本对应的参数,而对应这里的脚本又没有修改,则会抛错,自己被坑的很惨)

master_ip_failover:故障自动切换时对vip管理的脚本,不是必须。如果我们使用keepalived的,我们可以自己编写脚本完成对vip的管理,比如监控mysql,如果mysql异常,我们停止keepalived就行,这样vip就会自动漂移。

master_ip_online_change:在线切换时对vip的管理,不是必须,同样可以自行编写简单的shell完成。

power_manager:故障发生后关闭主机的脚本,不是必须。

send_report:因故障切换后发送报警的脚本,不是必须,可自行编写简单的shell完成。

4. 搭建主从复制环境(binlog模式异步复制)

注意:所有slave上的replicate-ignore-db设置必须相同,MHA在启动时候会检测过滤规则,如果过滤规则不同,MHA不启动监控和故障转移。

在整个复制集群中,都是使用基于binlog模式的复制,关于复制构建请看MySQL基于日志点做主从复制(二)。下面只给出一些复制相关操作。

1)在mysql01上创建复制用户

2)在mysql02上连接mysql01

3)在mysql03上连接mysql01

4)两台slave服务器设置read_only(从库对外提供读服务,只所以没有写进配置文件,是因为随时slave会提升为master)

5)创建监控用户(在master上执行,也就是10.99.73.9)

到这里整个复制集群环境已经搭建完毕,剩下的就是配置MHA软件了。

5. 配置MHA Manager

1)创建MHA的工作目录,并且创建相关配置文件(在软件包解压后的目录里面有样例配置文件)。

修改masterha_default.cnf全局配置文件,适用于所有app.cnf。

Tips:对于masterha_secondary_check二次检测脚本,master_host和master_ip参数一般都设置最好,没有主机名可以都设置为同一个IP即可。另外,对于二次检测方式ping_type的参数可以有 SELECT 和 INSERT,很容易看出,一个是用读来检测,一个是用写来检测(通过创建库,有风险)。

如果只修改app1.cnf配置文件,只针对单个应用生效,但是app1.cnf的配置参数优先级高于masterha_default.cnf,一般都会在app1.cnf包含masterha_default.cnf所有参数,而不使用masterha_default.cnf文件。

candidate_master设置为1时,表示为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave。默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master check_repl_delay=0。

你也可以设置no_master=1,表示此节点不参选master。

2)设置relay log的清除方式(在每个slave节点上)

注意:MHA在发生切换的过程中,从库的恢复过程中依赖于relay log的相关信息,所以这里要将relay log的自动清除设置为OFF,采用手动清除relay log的方式。在默认情况下,从服务器上的中继日志会在SQL线程执行完毕后被自动删除。但是在MHA环境中,这些中继日志在恢复其他从服务器时可能会被用到,因此需要禁用中继日志的自动删除功能。定期清除中继日志需要考虑到复制延时的问题。在ext3的文件系统下,删除大的文件需要一定的时间,会导致严重的复制延时。为了避免复制延时,需要暂时为中继日志创建硬链接,因为在Linux系统中通过硬链接删除大文件速度会很快。(在mysql数据库中,删除大表时,通常也采用建立硬链接的方式)

MHA节点中包含了pure_relay_logs命令工具,它可以为中继日志创建硬链接,执行SET GLOBAL relay_log_purge=1,等待几秒钟以便SQL线程切换到新的中继日志,再执行SET GLOBAL relay_log_purge=0。

pure_relay_logs脚本参数如下所示:

3)设置定期清理relay脚本(两台slave服务器)

添加到crontab定期执行

purge_relay_logs脚本删除中继日志不会阻塞SQL线程,下面我们手动执行看看什么情况。

6. 检查SSH配置(masterha_check_ssh)

检查MHA Manger到所有MHA Node的SSH连接状态。

可以看见各个节点ssh验证都是ok的。如果你使用了masterha_secondary_check做二次验证,那么这里面提到的机器也必须SSH互信。

MHA恢复slave是并行的,也就意味着恢复需要开启多个ssh通道,所以为了安全和谨慎,在/etc/ssh/sshd_config(默认10)提高MaxStartups的数量,然后重启sshd,或者reload。

7. 检查整个复制环境状况(masterha_check_repl)

暂时先注释配置文件中master_ip_failover_script= /usr/local/bin/master_ip_failover这个选项,不然这个检查过不去的。后面引入keepalived后和修改该脚本以后再开启该选项就ok了。

通过masterha_check_repl脚本查看整个集群的状态。

如果发现如下错误:

提示很明显,找不到mysqlbinlog和mysql,添加一个环境变量就可以解决了。

如果检测到失败,会返回错误:

* 复制过滤规则不同,SQL线程有错误,复制环境中存在多个master 。

* IO线程stopped状态。

* SQL线程stopped状态。

* 复制延迟太长(–seconds_behind_master=(seconds))。

* 配置文件有问题。

masterha_check_repl的一些参数,可以加到配置文件中。

8. 检查MHA Manager的状态(masterha_check_status)

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

注意:如果正常,会显示”PING_OK”,否则会显示”NOT_RUNNING”,这代表MHA监控没有开启。

9. 开启MHA Manager监控(masterha_manager)

启动参数介绍:

--conf

用于指定应用&局部配置文件。

--remove_dead_master_conf

设置了这个参数后,如果MHA failover结束后,MHA Manager会自动在配置文件中删除dead master的相关项。如果不设置,由于dead master的配置还存在文件中,那么当MHA failover后,当再次restart MHA manager后,会报错(there is a dead slave previous dead master)。

--manger_log

日志存放位置。

--ignore_last_failover

在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之所以这样限制是为了避免ping-pong效应。该参数代表忽略上次MHA触发切换产生的文件,默认情况下,MHA发生切换后会在日志目录,也就是上面我设置的/data产生app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为–ignore_last_failover。

--wait_on_monitor_error=(seconds)

这个功能主要用在自动监控和failover上,如果在监控期间发生了错误,masterha_manager会等待wait_on_monitor_error=N 秒,然后退出,默认是0
。如果遇到错误,在restart监控前最好还是等等。

--ignore_fail_on_start

默认情况下,如果一个或者多个slave down掉了,master monitor进程就会停掉,就算你设置了ignore_fail。如果设置了–ignore_fail_on_start参数,ignore_fail标记了slave挂掉也不会让master monitor进程停掉。

查看MHA Manager监控是否正常:

可以看见已经在监控了,而且master的主机为10.99.73.9。

PS:如果起不来,注释master_ip_failover_script。

10. 查看启动日志

其中”Ping(SELECT) succeeded, waiting until MySQL doesn’t respond..”说明整个系统已经开始监控了。

11. 关闭MHA Manage监控

关闭很简单,使用masterha_stop命令完成。

12. 简单的自动failover测试

在整个MHA加复制集群都搞定的情况下,MHA正常监控下,就可以进行failover测试了。

最好可以先对mysql master进行压测,打入大量的数据(我测试过程中发现如果没有数据直接切换MHA会卡主),使用sysbench生成测试数据(使用yum快速安装)

在主库(10.99.73.9)上进行sysbench数据生成,在sbtest库下生成sbtest表,共100W记录。

然后可以选择直接关闭mysql master,看mha的切换。

测试过程中,发现当mha进行一次切换后,其进程就自动退出了。观察其配置文件,会发现mysql01的配置文件被删除了,是为了防止误操作。

可以看一下整个failover过程,日志信息如下:

由mha切换日志可以看出,整个故障切换已经完成了。整个过程各个阶段核心切换逻辑简化后如下:

Phase 1:配置文件检查

Phase 2:非存活Master关闭服务

Phase 3:Master恢复

Phase 3.1:获取与Master延迟最小的Slave节点和延迟最大的Slave节点

Phase 3.2:生成Master与延迟最小的Slave节点的差异binlog并保存到manager节点

Phase 3.3:找出新的New Master,并且在延迟最小的Slave的Relay log中寻找延迟最小Slave与延迟最大Slave之间差异的binlog日志是否存在

Phase 3.3:如果New Master不是最新的Slave节点,那么需要从最新Slave的Relay log中生成它们之间的差异Relay log

Phase 3.4:New Master恢复差异Relay log和差异binlog日志,随后获取Master binlog位点信息

Phase 4:Slaves恢复

Phase 4.1:多线程生成延迟最小的Slave节点与其他一个或多个Slave差异Relay log

Phase 4.2:多线程恢复Slave节点与延迟最小的Slave之间的差异Relay log,并且恢复manager节点保存的差异binlog,然后change master到NEW MASTER节点

Phase 5:New Master清理Slave信息,并删除掉MHA配置文件中的选主信息防止误操作等

然后查看mysql02是否为我们所设置的那样切换为主了(对于mysql02设置了candidate_master=1)。

由这三个条件,可以看出切换已经成功了。show slave status时没有slave信息,并且前面我们设置的read_only给关闭了;另外,mysql03成为了mysql02的slave。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (3)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!

(2)个小伙伴在吐槽
  1. 第五步的创建[root@mha ~]# mkdir /data/mysql/tmp -p不应该是在mha服务上创建的吧?应该是在master服务器上生成的吧! 五、配置MHA Manager 1)创建MHA的工作目录,并且创建相关配置文件(在软件包解压后的目录里面有样例配置文件)。 [root@mha ~]# mkdir /data/mysql/tmp -p
    John2017-11-09 10:49 Windows 7 | Firefox浏览器 56.0
    • 对,在MySQL Master上创建,我写错地方了。ths
      彭东稳2017-11-13 14:52 Mac OS X | Chrome 61.0.3163.79