MHA知识大集合

1,808 阅读11分钟

MHA介绍

MHA是一套用于高可用环境下自动故障切换和主从提升的软件,在0~30秒以内就可以完成故障的切换并且能最大限度的保证数据一致性。 github.com/yoshinorim/… 有如下好处: a、自动故障转移快,秒级就能完成故障切换 b、可以结合半同步复制,保证主从数据的一致 c、manager节点可以管理多个MHA集群系统 d、在运行过程中,manager节点只是周期性的发送ICMP包,对性能的影响极低 e、只要mysql 复制技术支持的引擎,MHA就支持 宕机后处理: 1、在master出现故障之后,mha会尝试到故障master节点上面保存未传输的binlog日志 2、识别复制环境中最新的slave确定下一个master是谁,当然也可以通过配置文件中直接指定谁是备用主 3、应用差异的中继日志到其它slave。在环境中可能存在各个slave不一致的情况,MHA需要等待所有slave应用完差异的relay log 4、应用在第一步中保存的binlog(这些binlog是还来不及传输到slave上的binlog) 5、提升最新的slave为master 6、其它节点进行change master操作

配置复制环境

配置复制环境

配置半同步复制

a)确认plugin dir mysql> show variables like '%plu%'; [root@mysql1 plugin]# ls -l semisync_* -rwxr-xr-x 1 7161 31415 425987 9月 14 2017 semisync_master.so -rwxr-xr-x 1 7161 31415 249167 9月 14 2017 semisync_slave.so b)安装插件 install plugin rpl_semi_sync_master SONAME 'semisync_master.so'; install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so'; c)确定插件已经正常安装 mysql>show status like '%semi%'; mysql> show plugins; d)启动半同步复制 set global rpl_semi_sync_master_enabled=1; set global rpl_semi_sync_master_timeout=3000; set global rpl_semi_sync_slave_enabled=1; 重启slave生效 e)确认是否已经开启 show status like ‘%semi%’; Rpl_semi_sync_master_clients:显示当前处于半同步模式下slave的数量 Rpl_semi_sync_master_status:显示master当前是否开启了半同步模式 Rpl_semi_sync_master_no_tx:当前未成功发送到slave的事务数量 Rpl_semi_sync_master_yes_tx 当前已成功发送到slave的事务数量

安装配置MHA

3.1 安装依赖包

yum localinstall -y perl-Log-Dispatch-2.26-1.el6.rf.noarch.rpm perl-Config-Tiny-2.12-1.el6.rfx.noarch.rpm perl-Parallel-ForkManager-0.7.5-2.2.el6.rf.noarch.rpm --此步骤中的包,在系统自带的yum中是没有的 yum localinstall perl-Log-Dispatch-2.26-1.el6.rf.noarch.rpm

yum install -y perl-DBD-MySQL perl-Time-HiRes perl-CPAN 可以使用yum直接安装 在0.56的MHA版本里面使用自带的版本(DBI 1.609,DBD 4.013)即可,如果环境中有了其它版本的DBI、DBD可能会导致在按照MHA node的时候报无法load DBD的错误

安装MHA

在所有节点上安装mha-node软件(包括managed节点),在规划的managed节点上面安装managed软件,安装遵循三部曲 #源码安装三部曲
perl Makefile.PL 注意执行这部的时候会检查需要的包,需要确定所有依赖组件都能被load make make install

3.3 配置MHA

3.3.1 Ssh配置 a)修改/etc/hosts文件,加入所有节点的ip信息 b)使用脚本配置ssh信任

./ssh_setup -user root -hosts "node1 node2 node3 node4" -advanced -noPromptPassphrase 3.3.2 数据库配置 a)配置从库read_only参数 set global read_only=1 说明:如果不配置read_only参数,在启动mha的时候会提示警告,但是不会出现error。 b)配置relay_log的清除方式 set global relay_log_purge=0 说明:在复制过程中可能会出现不同步的情况,比如slave1比slave2块,那么在切换的时候就需要把slave1上的relay log应用到slave2上,如果不设置relay_log_purge=0那么可能会出现丢失relay log的情况。在mha环境中,可以使用MHA提供的脚本去清除relay log文件。 eg:可以使用MHA提供的脚本进行删除 purge_relay_logs --user=root --password=123456 --port=3306 -disable_relay_log_purge --workdir=/data/

3.4 部署relay log清理脚本

在MHA发生故障的切换过程中,slave的恢复需要依赖于最新的relay log,如果设置为relay log的自动清除,那么relay log会在sql线程执行完毕后自动清理relay log,在发生故障切换的时候就可能会导致无法做恢复,所以需要设置为relay log为手工清除,在MHA中可以使用MHA提供的pure_relay_logs脚本来进行监控。

a)pure_relay_logs清理的原理:

1、为relay log创建硬链接

2、set global relay_log_purge=1;flush logs; set global relay_log_purge=0;

3、删除relay log

b)使用方式:

purge_relay_logs --user=admin --password=123 --host=172.1.1.103 --port=3306 -disable_relay_log_purge --workdir=/data/

c)部署自动清理脚本(所有节点部署,不要使用vip)

--编辑脚本

#!/bin/bash

host=172.1.1.103

user=admin

passwd=admin

port=3306

log_dir='/var/log/masterha/tpcc/'

work_dir='/data/mysql/data/'

purge='/usr/local/bin/purge_relay_logs'

if [ ! -d $log_dir ]

then

mkdir $log_dir -p

fi

purge --user=user --password=passwd --disable_relay_log_purge --host=host --port=port --workdir=work_dir >> $log_dir/purge_relay_logs.log 2>&1 --添加权限

chmod +x /root/script/purge_relay_log.sh

--配置crontab

###3.5 编写mha配置文件 [root@node4 ~]# cat /etc/masterha/slave.conf [server default] manager_log=/var/log/masterha/tpcc/manager.log manager_workdir=/var/log/masterha/tpcc master_binlog_dir=/data/my3306/binlog master_ip_failover_script=/usr/local/bin/master_ip_failover master_ip_online_change_script=/usr/local/bin/master_ip_online_change password=123 ping_interval=3 remote_workdir=/data/tmp repl_password=123 repl_user=repl secondary_check_script=/usr/local/bin/masterha_secondary_check -s node2 -s node3 ssh_user=root user=admin [server1] candidate_master=1 hostname=172.1.1.101 port=3306 [server2] #candidate_master=1 hostname=172.1.1.102 port=3306 [server3] hostname=172.1.1.103 port=3306 --user GRANT ALL PRIVILEGES ON . TO 'mha_admin'@'172.1.1.%' 注意:secondary_check_script的作用是二次检测master的网络,如果没有配置该参数,只要managed到master的网络出了问题就会认为master故障,但是可能是managed本身的网络出了问题。当发现master网络不通的时候,managed节点会通过secondary_check_script设置的其它节点去检查网络,如果managed通过配置的其它节点去检查master,master状态也有问题那么就认为master真的是挂了,如果managed节点到secondary_check_script配置的任何一个节点都不通就会认为是managed的网络故障,不会发起failover。注意secondary_check_script配置节点也需要配置ssh等效性。 说明:manager_workdir是mha的工作目录,在切换的时候会把master主机上面的binlog日志保存到manager节点上的manager_workdir目录中,所以必须要保证有足够的空间,如果没有则会自动创建一个。 master_binlog_dir :指定masterbinlog的位置,如果指定位置错误会报错Failed to save binary log: Binlog not found from /data/my3306/binlog master_ip_failover_script:MHA在检测到故障后,只是会进行提升master和对其它slave做change master的操作,如果还需要执行什么脚本,可以通过这个参数去指定。一般用于keepalive切换VIP,同那个online切换脚本一样,脚本中的VIP配置只是用于MHA日志中输出的VIP,决定真正VIP的还是keepalive配置文件中的那个VIP user:MHA的管理用户,mysql中的,默认情况下是root,需要的权限较高。因为需要执行start/stop slave,change master ,reset slave等操作。 Ssh_user:使用ssh登录的用户,用于获取binlog remote_workdir:在发生failover的时候,master需要保存自己的binlog,这个路径就会放在remote_workdir指定的目录中

3.6 检查ssh和复制情况(manager执行)

masterha_check_ssh --conf=/etc/masterha/slave.conf masterha_check_repl –conf=/etc/masterha/slave.conf 注意:在执行检查的时候需要暂时注释掉master_ip_failover_script,因为此时这个脚本还未有创建

3.7 启动MHA

nohup masterha_manager --conf=/etc/masterha/slave.conf --remove_dead_master --ignore_last_failover >> /var/log/masterha/tpcc/manager.log 2>&1

注意:建议使用追加的方式,否则每次启动都会覆盖上次的日志。

   启动MHA之前,配置复制参数

3.8 编写MHA管理脚本

附件

3.9 检查

4 安装配置keepalived

4.1安装配置keepalived

Yum install keepalived

所有节点都需要安装

4.2 编辑keepalived配置文件

global_defs {

notification_email {

 root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id mysql2

}

vrrp_instance VI_20 {

state BACKUP

nopreempt

interface eth0

virtual_router_id 20

priority 150

advert_int 5

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

172.1.1.100 label eth0:1

}

}

注意:1、虽然keepalive也能检查mysql的状态,但是为了避免keepalive和MHA切换不同步的问题,keepalive只用来挂载VIP

2、router_id必须一样认证也需要一样

3、都需要配置为backup状态,因为如果是master-backup模式,故障节点修复后,如果priority叫高就会抢占vip,这时候MHA并没有切换就会造成故障。

4.3 启动keepalive和MHA

Service keepalived start

nohup masterha_manager --conf=/etc/masterha/slave.conf --remove_dead_master --ignore_last_failover >/var/log/masterha/tpcc/manager.log 2>&1

说明:--remove_dead_master,如果不加这个参数,那么在发生故障切换的时候是不会从配置文件中清除dead master的信息,这个时候如果在dead master上的故障未修复,直接启动MHA,那么会报错。

--ignore_last_failover,如果不加该参数,那么在默认情况下MHA在做完failover之后的6个小时之内是不会再次做failover的(目的是避免频繁的切换),如果发生故障切换,会报错“Current time is too early to do failover again”,加上这个参数之后就会忽略最近一次切换。

后期发现的问题:Keepalived如果在主从都启动,在切换的时候可能会导致vip挂错节点的问题。如果只在master上面启动keepalive,在slave上面关闭,就没有这个问题

4.4 切换检查

检查MHA是否能正常切换

检查VIP是否能跟随MHA切换

5 MHA在线切换

5.1 切换前提

l 所有slave的io_thread和sql_thread都在运行中。

l 所有slave的Seconds_Behind_Master小于或等于running_updates_limit的值,该参数如果没有显示指定的话,则默认为1s。

5.2 切换方式

a)停止MHA监控

masterha_stop --conf=/etc/masterha/slave.conf

b)切换

/usr/local/bin/masterha_master_switch --conf=/etc/masterha/slave.conf --master_state=alive --new_master_host=172.1.1.102 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=2

c)检查主备的read_only参数

注意:

1、需要有master_ip_online_change这个脚本

2、master_state用于指定切换时master的状态,如果master出现故障,但是自动failover出现故障,那么这个时候就可以使用master_state=dead的方式切换

3、orig_master_is_new_slave 用来控制orig master的状态,如果不加这个参数,orig master在切换后就会脱离复制环境,加了该参数在切换之后,orig master会自动切换为new master的从。

4、running_updates_limit,如果延迟在该参数的指定范围内都会进行切换。

5.3 切换过程

1、分析配置

--分析当前的配置环境

--执行flush no_write_to_binlog tables

2、阻止对原master的写入

--设置old master的read_only=1

--disabled old master vip

--kill所有的连接

--执行flush tables with read lock;

3、提升new master

--等待new master执行完成所有的relay log

--获取新master上面的binlog信息

--在new master上面启动vip

--取消old master上面的read lock

--执行change master的操作

4、清理new master上面的slave信息

5.5 注意事项

所有的slave都必须处于活动状态MHA才能进行切换。

MHA启动之后就只会监控master的状态,对slave的重启、增加、移除等都不会影响MHA,如果增加了slave,需要更新MHA的配置文件。

如果MHA最近一次切换距离现在太近,将不会进行故障切换。

6.MHA常见的坑

6.1 原主库failover之后不能加入复制拓扑

对于gtid_purge来说,如果当前数据库的角色是主库,那么gtid_purge表示这些gtid已经不在当前binlog中了;如果当前数据库是备库,那么表示已经执行过的gtid。那么在主库做了failover之后,那么原来主库中的gtid purge值肯定需要修改,如果直接使用change master加入复制必定会报错。 方法:reset master; set @@global.gtid_purge=xxx; change master to xxx; start 具体的gtid_purge信息可以在mha的切换日志中保留

6.2 failover之后,加入复制拓扑之前保留binlog

因为在原主库加入复制之前需要做reset master操作,这个过程会清理当前环境中所有的binlog,如果在清理了之后发生数据库损坏需要使用binlog做恢复的时候,那么就会因为没有binlog导致无法做数据恢复。

6.3 MHA+keepalived时候VIP的坑

在MHA+keepalived环境中,vip必须和master绑定在一起的。如果所有节点都启动了keepalive,并且所有节点的优先级都配置为一样,那么在发生failover的时候就能导致master和vip不在一个节点上面(毕竟mha不能控制keepalived)如果备库刚好又没有配置read_only那么就可能导致脑裂的问题。 解决方法有两个:

  • 只在master上面启动keepalived,因为在做failover的时候切换脚本会做service keepalived start、stop的操作,这样就可以保证master上面一定会运行keepalived
  • 如果一定要启动keepalived,那么在mha配置文件中指定备用master,同时调整该备用master上面keepalived的优先级。

常见问题处理

1、Sat Dec 14 21:56:45 2019 - [error][/usr/local/share/perl5/MHA/ServerManager.pm, ln492] Server 172.1.1.22(172.1.1.22:3306) is dead, but must be alive! Check server settings 原因:要启动mha,必须要mha配置文件中的所有节点都正常启动

2、Sat Dec 14 22:02:43 2019 - [error][/usr/local/share/perl5/MHA/ServerManager.pm, ln653] There are 2 non-slave servers! MHA manages at most one non-slave server. Check configurations. 原因:在mha配置的节点中发现了两个master,一般情况下是因为做了failover之后,启动了原主库,在原主库还没有加入新复制拓扑的情况下就启动mha,这个时候就会报错