mha安装使用手册

mha安装使用手册

注:目前mha最新的版本代码已经不放到google code网站了,而是放在github上,最新的版本为0.57,github链接如下:
mha manager:https://github.com/yoshinorim/mha4mysql-manager
mha node:https://github.com/yoshinorim/mha4mysql-node

1、安装

1.1. 安装环境说明
  • 这里只演示一主一从的步骤(即主从所有节点安装相同的依赖包,管理节点和数据节点的mha包都安装),一主多从或者两主一从,两主多从的步骤类似
  • 复制环境
    master:10.10.30.169
    slave1:10.10.30.146
    slave2:10.10.30.155
    slave3:10.10.30.140
1.2. 安装步骤
1.2.1. 安装依赖包
yum install -y perl-DBD-MySQL
  • 从库或者管理节点
  • 如果有专门的管理节点,从库就只安装perl-DBD-MySQL
yum install -y perl-DBD-MySQL
  • 如果没有管理节点,那么在所有的主从节点都安装如下依赖包
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-MIME-Lite perl-Params-Validate
1.2.2. 安装mha软件
rpm -Uvh mha4mysql-manager-0.56-0.el6.noarch.rpm  mha4mysql-node-0.56-0.el6.noarch.rpm
PS:rpm包中不包含配置文件样例和故障转移主库VIP(master_ip_failover)、在线切换主库VIP(master_ip_online_change),需要到官网下载源码包,源码包中的sample目录下有
1.2.3. 配置所有节点之间免密码登录,包括自己也要能免密码登录自己,所以这里配置为只使用同一对密钥(在主库上操作即可)
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@slave
ssh-copy-id -i .ssh/id_rsa.pub root@master
scp ~/.ssh/id_rsa root@slave:~/.ssh/
  • 因为mha运行时需要用到/usr/bin下的两个mysql命令(貌似路径写死了,更改/etc/profile对mha无效),所以建立两个软连接
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql

如果发现有这个文件,那么请使用如下命令检查下是否是低版本的rpm包所装,如果是,则卸载掉这个包,然后再重新做软连接
# rpm -qf /usr/bin/mysqlbinlog 
mysql-5.1.73-3.el6_5.x86_64
# rpm -e mysql-5.1.73-3.el6_5.x86_64 --nodeps
1.2.4. 从库设置只读和关闭自动清理binlog(必须设置,否则做masterha_check_repl这个检测步骤的时候会不通过)

set global read_only=1;
set global relay_log_purge=0;

1.2.5. 在所有节点上创建如下目录
# 创建mha的配置文件目录
mkdir /etc/masterha/app1 -p
# 创建mha的工作目录
mkdir /var/log/masterha/app1 -p
1.2.6. 创建一个超级管理员以及复制帐号,必须具有远程连接权限
grant all on *.* to AAA@'%' identified by 'letsg0' with grant option;
grant replication slave on *.* to repl@'%' identified by 'repl';
1.2.7. 配置管理节点配置文件(这里是配置在从库上)
cat /etc/masterha/app1/app1.conf
[server default]
#mha manager工作目录
manager_workdir = /var/log/masterha/app1  #管理节点工作目录,如果管理节点也是数据节点,那么建议设置为与remote_workdir 不同的目录,如:/tmp
manager_log = /var/log/masterha/app1/app1.log
remote_workdir = /var/log/masterha/app1  #mysql数据节点的工作目录
# MySQL管理帐号和密码
user=qogir_env
password=PkC4toqKwgKylN7_2NR1
# 系统ssh用户
ssh_user=root
# 复制帐号和密码
repl_user=repl 
repl_password= repl
# 监控间隔(秒)
ping_interval=1
manager_log=/var/log/masterha/app1/manager.log

[server1]
hostname=10.10.30.169
master_binlog_dir = /archive/mysqldata1/binlog/
port=3306


[server2]
hostname=10.10.30.146
master_binlog_dir = /archive/mysqldata1/binlog/
candidate_master=1
check_repl_delay=0
port=3306

[server3]
hostname=10.10.30.155
master_binlog_dir = /archive/mysqldata1/binlog/
candidate_master=1
check_repl_delay=0
port=3306

#[binlog1]  #如果配置了binlogserver,可以这样加到配置文件里
#hostname=binlog_host1

PS:关于binlogserver支持的官方原文
Starting from MHA version 0.56, MHA supports new section [binlogN]. In binlog section, you can define mysqlbinlog streaming servers. When MHA does GTID based failover, MHA checks binlog servers, and if binlog servers are ahead of other slaves, MHA applies differential binlog events to the new master before recovery. When MHA does non-GTID based (traditional) failover, MHA ignores binlog servers.

1.2.8. 检测ssh面密钥以及复制配置是否正确
# 检测免密钥环境需要看到[info] All SSH connection tests passed successfully.提示才算通过
masterha_check_ssh --conf=/etc/masterha/app1/app1.conf 
# 检测复制环境需要看到MySQL Replication Health is OK. 提示才算通过
masterha_check_repl --conf=/etc/masterha/app1/app1.conf 
# 检测通过之后,把这个配置文件复制到其他所有节点
1.2.9. 测试启动MHA管理节点、检测管理节点状态、停止管理节点
nohup masterha_manager --conf=/etc/masterha/app1/app1.conf >> /var/log/masterha/app1/manager.log 2>&1 &
# 此时可以查看日志/var/log/masterha/app1/manager.log 里是否有报错信息,如果不报错信息,则继续往下
# 检测管理节点状态,需要看到类似app1 (pid:14913) is running(0:PING_OK), master:10.10.30.169 提示信息才表示无误
masterha_check_status --conf=/etc/masterha/app1/app1.conf 
masterha_stop --conf=/etc/masterha/app1/app1.conf 
# 停止管理节点程序之后,检测下进程是否被关掉
ps aux |grep masterha |grep -v grep
  • PS:masterha_check_status 可能会返回的状态值及其对应的解释如下表

2、测试

2.1. 现在测试故障转移,把管理节点启动起来,然后把主库停掉,再观察管理节点的日志输出
# 管理节点(装在从库上)启动
nohup masterha_manager --conf=/etc/masterha/app1/app1.conf >> /var/log/masterha/app1/manager.log 2>&1 &
# 主库(10.10.30.169)停止mysql
pkill mysqld
# 查看管理节点日志
vim /var/log/masterha/app1/manager.log
...
Tue Sep 27 17:00:48 2016 - [info] The latest binary log file/position on all slaves is mysql-bin.000118:413749799  #找拥有最新relay log的从库,这里找到所有从库最新的位置都处在对应故障主库的mysql-bin.000118:413749799 这个binlog pos
Tue Sep 27 17:00:48 2016 - [info] Retrieved Gtid Set: d5086143-7f00-11e6-8f06-00163e5b1964:3885658-59476900 #这个是最新从库的relay log中对应主库的GTID位置
...
Tue Sep 27 17:00:48 2016 - [info]  Searching from candidate_master slaves which have received the latest relay log events..  #开始从备选主库中查找拥有最新的relay log events的从库
Tue Sep 27 17:00:48 2016 - [info] New master is 10.10.30.146(10.10.30.146:3306)  #10.10.30.146胜出
Tue Sep 27 17:00:48 2016 - [info] Starting master failover..  #开始执行master切换
Tue Sep 27 17:00:48 2016 - [info]
From:
10.10.30.169(10.10.30.169:3306) (current master)
 +--10.10.30.146(10.10.30.146:3306)
 +--10.10.30.155(10.10.30.155:3306)

To:
10.10.30.146(10.10.30.146:3306) (new master)  #10.10.30.146被选举为新的master,从这里from ...to ...可以看到从from复制架构变成了to 复制架构,故障主库10.10.30.169被踢出复制组
 +--10.10.30.155(10.10.30.155:3306)

Tue Sep 27 17:00:48 2016 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.10.30.146', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';  #这里记录着新主库数据的位置,其他从库就是使用这句切换到新主库的,你可以看到,开启了GTID之后,这里change master语句中并没有binlog pos位置,就跟你手动配置GTID时一样
Tue Sep 27 17:00:48 2016 - [info] Master Recovery succeeded. File:Pos:Exec_Gtid_Set: mysql-bin.000116, 257595953, 0e9de29e-7f01-11e6-8f08-00163e4c2511:1-5,
d5086143-7f00-11e6-8f06-00163e5b1964:1-59476900    #这里记录着新主库的数据对应着故障主库的GTID位置以及binlog pos
...
Tue Sep 27 17:00:49 2016 - [info] Resetting slave info on the new master..  #等到从库都切换到新主库上去之后,新主库清理之前连接故障主库的信息
Tue Sep 27 17:00:50 2016 - [info]  10.10.30.146: Resetting slave info succeeded.
Tue Sep 27 17:00:50 2016 - [info] Master failover to 10.10.30.146(10.10.30.146:3306) completed successfully. #看到这里表示主库切换全部动作完成
2.2. 现在来看看,故障主库恢复之后,如何加进复制组中
2.2.1. 首先先看看新旧主库的show master status输出
old master:
>show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000119
         Position: 194
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: d5086143-7f00-11e6-8f06-00163e5b1964:1-59476900
1 row in set (0.00 sec)

new master:
show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000116
         Position: 257595953
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 0e9de29e-7f01-11e6-8f08-00163e4c2511:1-5,
d5086143-7f00-11e6-8f06-00163e5b1964:1-59476900 #这个是对应旧主库的数据GTID
1 row in set (0.00 sec)

# 如果old master的Executed_Gtid_Set大于新主库中对应UUID哪一个的事物号,那么就表示,新主库丢了数据了,这个时候你需要自行从旧主库上提取这部分数据差异出来,然后与应用研发核对这部分数据是否需要补回新主库中,这个比较蛋疼,补完数据之后,还得把旧主库的数据干掉重新做成从库;如果旧主库的GTID与新主库对应的UUID那一个GTID相等,那么恭喜你 ,表示数据并没有丢失。
PS:如果你是使用的传统复制,那么后续旧主库恢复之后,有没有多数据需要去切换日志里边找 latest binary log file/position记录,这个就是主库挂掉之后,其他从库所拥有的最新的对应旧主库的binlog pos,然后,使用mysqlbinlog在旧主库上提取这个位置之后的数据,再人工确认这些数据是否要补到新主库上
2.2.2. 把旧主库设置一下read_only

set global read_only=1;
set relay_log_purge=0;
注意:作为从库加入mha的任何实例,都不能少这个步骤

2.2.3. 然后在mha管理节点的切换日志中,找到change master语句,复制下来,填上密码就可以执行了
 # grep 'CHANGE MASTER TO' /var/log/masterha/app1/manager.log |tail -1
 CHANGE MASTER TO MASTER_HOST='10.10.30.155', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';
2.3. 现在测试下手工在线切换和故障切换功能
2.3.1. 主库存活在线切换(手工切换需要关闭管理进程)
# masterha_master_switch --conf=/etc/masterha/app1/app1.conf --master_state=alive --new_master_host=10.10.30.169 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=100

# 如果你是跟着文档流程做到这里,在切换过程中会有三个提示,输入yes回车即可
* It is better to execute FLUSH NO_WRITE_TO_BINLOG TABLES on the master before switching. Is it ok to execute on 10.10.30.155(10.10.30.155:3306)? (YES/no): yes  #这里询问你是否需要在切换之前在当前主库上执行FLUSH NO_WRITE_TO_BINLOG TABLES语句
* Starting master switch from 10.10.30.155(10.10.30.155:3306) to 10.10.30.169(10.10.30.169:3306)? (yes/NO): yes  #确认是否开始执行切换
* master_ip_online_change_script is not defined. If you do not disable writes on the current master manually, applications keep writing on the current master. Is it ok to proceed? (yes/NO): yes  #检测到master_ip_online_change_script 么有配置,因为到目前为止,并没有配置VIP,所以会有这个提示,但是要注意,切换的过程中,不要在主库写数据

# 切换成功之后,应该看到如下提示:
Thu Sep 29 12:47:37 2016 - [info] Switching master to 10.10.30.169(10.10.30.169:3306) completed successfully.

# 常用参数解释如下:
--orig_master_is_new_slave 切换时加上此参数是将原 master 变为 slave 节点,如果不加此参数,原来的 master 将不会作为从库加入到新主库上,要使用这个参数,配置文件中必须配置repl_password参数,因为新主库并不知道旧主库的复制帐号密码是什么
--running_updates_limit=100,故障切换时,候选master 如果有延迟的话, mha 切换不能成功,加上此参数表示延迟在此时间范围内都可切换(单位为s),但是切换的时间长短是由recover 时relay 日志的大小决定、
--master_state=alive  告诉mha,当前主库是活者的,对应的还有一个值是dead,即告诉mha当前主库死了
 --new_master_host  指定新的主库是谁
--new_master_port  指定新主库的数据库端口
2.3.2. 主库宕机在线切换
# 先把主库stop掉
# pkill mysqld
# 然后到管理节点上去执行切换命令
# masterha_master_switch --master_state=dead --conf=/etc/masterha/app1/app1.conf --dead_master_host=10.10.30.169 --dead_master_port=3306 --new_master_host=10.10.30.155 --new_master_port=3306 --ignore_last_failover --remove_dead_master_conf

# 如果你是跟着文档流程做到这里,在切换过程中会有两个提示,输入yes回车即可
* Master 10.10.30.169(10.10.30.169:3306) is dead. Proceed? (yes/NO): yes   #让你确认下主库是否真的死了
* Starting master switch from 10.10.30.169(10.10.30.169:3306) to 10.10.30.155(10.10.30.155:3306)? (yes/NO): yes  #让你确认是否开始执行切换

# 切换成功之后,应该看到类似如下提示
Master failover to 10.10.30.155(10.10.30.155:3306) completed successfully.

# 常用参数解释
--remove_dead_master_conf      该参数代表当发生主从切换后,老的主库的ip将会从配置文件中移除。默认情况下,主库切换之后并不会修改配置文件
--manger_log                            日志存放位置
--ignore_last_failover                 在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之所以这样限制是为了避免ping-pong效应。该参数代表忽略上次MHA触发切换产生的文件,默认情况下,MHA发生切换后会在日志目录,也就是上面我设置的/data产生app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为--ignore_last_failover,另外,新版本0.56可以不使用这个参数,也不需要专门去删除app1.failover.complete文件
--dead_master_host  指定死掉的主库的IP
--dead_master_port  指定死掉的主库的数据库端口

# 查看app1.conf文件,会发现死掉的主库配置被删掉了
grep '10.10.30.169' /etc/masterha/app1/app1.conf 

# 在线切换需要满足如下条件
* 所有从库的IO和SQL线程必须为运行状态
* 所有从库的Seconds_Behind_Master 的值必须小于--running_updates_limit 参数指定的数值
* 在主库上,show processlist出来的更新(个人觉得这里应该是指的对数据有变更操作的任何请求,而不仅仅是update)请求不能有超过--running_updates_limit 参数指定的数值的时间
2.3.3. 其他参数

--interactive=(0|1) 如果你想非交互式的执行切换,那么设置这个参数为0,默认是1,要使用该选项,你需要确定主库的状态是dead还是online,或者其他程序调用masterha_master_switch切换命令时使用
--skip_change_master 0.56版本新增功能, 默认情况下,主库切换时,其他从库会change到新主库上,这个参数可以在从库数据恢复之后,跳过change 到新主库以及跳过start slave,这样你就可以手动到从库上去再次确认数据有没有恢复成功
--skip_disable_read_only 0.56版本新增功能,默认情况下,主库切换到新主库时,新主库会执行set global read_only=0; 打开新主库可读写,加上这个参数之后,跳过设置read_only=0语句
--wait_until_gtid_in_sync(0|1) 0.56版本新增的功能,默认为1,表示发生故障转移时,MHA会等待其他从库追赶上新主库的GTID位置,如果设置为0,则不会等待
--ignore_binlog_server_error 0.56版本新增功能,表示在故障转移时,跳过任何binlog server的错误
--skip_lock_all_tables 默认情况下,在执行主库切换的时候,旧主库会执行flush table with read lock语句来确保主库停止写,但是执行flush table with read lock是一个昂贵的操作,如果你能够人工判断并确认主库没有写操作,那么可以使用这个选项来跳过执行这个语句。master_ip_online_change_script 这个参数并杀掉所有的客户端连接

2.3.4. 现在,把VIP功能加进来,然后再重复前面的手工切换步骤,看看切换是否正常

VIP切换功能依赖master_ip_failover和master_ip_online_change两个脚本,master_ip_failover是故障切换VIP的脚本,master_ip_online_change是在线切换VIP的脚本,这两个脚本默认在rpm包里是没有的,需要到源码包的sample/scripts目录下获取,把scripts目录放到目录/etc/masterha/下

vim /etc/masterha/app1/app1.conf   #把下面一段配置加到/etc/masterha/app1/app1.conf 里(注:线面一段参数除故障转移,还包括发生切换的通知脚本,以及使用其他网络路径二次检测确认主库是否有故障的脚本,以及在检测到主库故障时,关闭主库的脚本)
master_ip_failover_script=/etc/masterha/scripts/master_ip_failover  #发生故障的时候,切换VIP的脚本,这个脚本不完整,需要自己修改,故障切换必须配置
# shutdown_script=/etc/masterha/scripts/power_manager  #在发生故障切换的时候,关闭主库的脚本,这个脚本要自己写,可不配置
#report_script=/etc/masterha/scripts/send_report  #在发生故障切换的时候,发送邮件的脚本,这个脚本不完整,需要自己修改,可不配置
master_ip_online_change_script=/etc/masterha/scripts/master_ip_online_change  #在线切换VIP的脚本,这个脚本不完整,需要自己修改,在线切换必须配置
# secondary_check_script= /usr/bin/masterha_secondary_check -s server03 -s server02 --user=root --master_host=server02 --master_ip=10.10.30.155 --master_port=3306               # 一旦MHA到server02的监控之间出现问题,MHA Manager将会尝试从server03登录到server02,可不配置

3、mha组件命令使用详解

  • 注意,这里讲到的都是日常维护和使用中需要手工调用的组件,还有一些是mha自动调用的组件在这里不做介绍,有星期可以自己去看命令帮助
3.1. masterha_manager命令只能监控主库的可用性,对于正在使用的复制架构,如果有从库的SQL线程或者IO线程意外终止,或者说有从库添加/删除/重启/停止,MHA监控是无法感知的(如果你对从库结构做了什么调整,那么请重启MHA监控程序),这个命令并不能发现(但是,这个命令在启动的时候,会调用masterha_check_repl来检查复制和ssh连通性,检查过了才会启动成功,否则无法启动成功),可以定期使用masterha_check_repl --conf=/etc/app1.cnf来检测一下,这个命令会检测所有的节点的复制架构是否正常,并及时发出警告信息,该工具可以发现如下错误信息:
  • MHA不能监控或者MHA不能做故障转移的错误(如:复制过滤规则不同,有节点的SQL线程错误停止了,你的配置文件中有配置两个或者更多的master)
  • 有节点的IO线程停止了
  • 节点SQL线程正常停止
  • 有节点的复制延迟大于N秒,使用参数--seconds_behind_master=(seconds)指定延迟大于多少就发出警告,默认是30s
    默认情况下,这个检测脚本也会调用masterha_check_ssh检测ssh的连通性,如果你确定ssh是可以的,不需要检测,那么就使用这个参数跳过ssh的检测--skip_check_ssh
PS:MHA故障转移过程中的一些判断逻辑、调用脚本的顺序等
  • 如果MHA在主库挂掉之后,做切换的时候,发现其他的从库连着不同的主库,即有的从库连接着的不是死掉那个主库,那么MHA监控程序报错并停止,如果你确定你某个从库需要连接其他的主库,那么可以在主机配置段落里加上参数 ignore_fail来忽略这个错误,让MHA继续做切换
  • 如果MHA最近一次故障转移失败,或者最近一次故障转移时间太近,那么MHA监控程序将拒绝启动,你可以使用选项 ignore_last_failover and wait_on_failover_error arguments来启动监控程序
  • 如果你在配置文件中配置了master_ip_failover_script and/or shutdown_script,那么MHA监控程序会调用这些脚本关闭死掉的主库电源,以避免脑裂发生
  • 如果主库操作系统直接挂了,那么在MHA提升新主库的时候,会把新主库对应旧主库的binlog pos位置记录在切换日志里,等到旧主库恢复之后,你可以根据这个位置到故障主库上去找出丢失那部分,然后自行决定要不要把这部分补到新主库上去。
  • 提升新主库的依据: 基于MHA配置文件和当前MySQL的设置,如果你想指定备用主库,可以在配置文件中对应的主机配置段落下用candidate_master=1参数指明,如果你不想某个从库作为备用主库,那么可以在配置文件中对应的主机配置段落下用no_master=1参数禁止这个从库被提升为新主库。
  • 根据最新的relay logs来识别出latest slave,根据IO线程读取的故障主库的位置做比较
  • 选举出latest slave之后,就需要把它提升为新的主库,首先生成差异的binlog/relay log,然后应用到这个新主库上,如果这个过程发生任何错误,那么MHA将终止后续的所有过程,包括其他从库的数据恢复操作
  • 使用master_ip_failover_script脚本激活新主库,比如激活VIP,或者特权用户什么的
  • 并行恢复其他slave,把差异binlog/relay log冰箱应用到其他从库上面,change master到新主库上,在这个阶段,如果有从库恢复数据失败,MHA不会终止这个恢复过程,会继续恢复,只是恢复失败的从库不能够从新主库上同步数据,而恢复成功的则继续从新主库上同步数据。
  • 如果你在配置文件中定义了report_script参数,那么MHA可以调用它发送邮件,在新的主库上关闭计划备份,升级内部管理工具的状态等
  • MHA读取配置文件中的信息,识别当前主库(MHA不会自己帮你创建复制环境,MHA只能在一个搭建好的复制环境下帮你监控主库)
  • MHA监控程序启动的时候,会检查所有从库的IO和SQL线程是否在运行,所有从库的Seconds_Behind_Master 是否大于2S(可以使用参数--running_updates_limit来改变这个值),在master上,show processlist输出中,有没有更新语句超过2S的
  • 默认情况下,MHA切换的时候,新的主库是自动识别的,如果你想要切换到某个指定的SLAVE上,可以使用选项--new_master_host指定
  • 如果你在配置文件中设置了 master_ip_online_change_script 参数,那么在MHA在线切换的过程中,就可以优雅地阻塞旧主库上的写请求(移除写请求的用户,并执行set global read_only=1;在旧主库上执行flush table with read lock语句获取全局读锁阻塞所有的写请求,如果你不想要加全局读锁这个步骤,可以使用参数--skip_lock_all_tables来跳过)
  • 所有从库上使用MASTER_LOG_POS() 函数来追赶主库
  • 允许新主库写:先在新主库上执行show master status语句把binlog file和binlog pos查出来,然后,如果你在配置文件中有定义 master_ip_online_change_script参数,那么MHA将调用这个脚本来创建写用户,并执行set global read_only=0;
  • 在其他从库上并行执行change master到新主库并start slave开始从新主库同步数据
3.2. masterha_stop

这个命令只是停止管理节点的监控程序,并不会停止MySQL,并且,使用这个命令来停止管理节点程序的时候,如果发现管理节点程序正在进行故障转移,则不会停止管理节点,会直接退出停止,这样做是为了避免出现在故障转移过程中出现不一致的复制配置信息,如果你是手动在shell命令行敲的kill pid方式杀掉管理节点的程序,请确保管理节点没有处于正在进行故障转移的阶段。

3.3. masterha_conf_host

有时候,你可能想要从配置文件中添加或者删除一个主机记录,比如你新安装了一个从库,又不想手动去编辑配置文件,那么,就可以使用这个命令来添加,命令如下:

masterha_conf_host --command=add --conf=/etc/conf/masterha/app1.cnf --hostname=db101

配置文件添加结果如下:

 [server_db101]
 hostname=db101

从结果上可以看到,hostname选项指定的db101被配置到了两个地方,[server_db101]为段落标签,如果你没有显式指定这个,就会使用server_$hostname的方式生成

如果你想手动指定段落标签(使用--block选项指定),且还想添加额外的一些参数(使用--params选项来指定,指定的内容用引号引起来,使用分号作为间隔),可以使用如下命令:

masterha_conf_host --command=add --conf=/etc/conf/masterha/app1.cnf --hostname=db101 --block=server100 --params="no_master=1;ignore_fail=1"

配置文件中添加结果如下:

 [server100]
 hostname=db101
 no_master=1
 ignore_fail=1

如果你想删除一个主机记录,可以使用如下命令(指定--block选项,不需要带这个主机的具体参数):

masterha_conf_host --command=delete --conf=/etc/conf/masterha/app1.cnf --block=server100

这样就可以把主机server100的整个段落配置从配置文件中删掉

参数解释:
--command=delete|add #从一个配置文件中添加/删除一个主机记录
--block #显式指定配置文件中,主机配置文件的段落标记
--conf #指定本地配置文件路径
--hostname #指定添加记录的主机名或者IP
--params #指定参数列表,使用分号作为参数间隔,所有参数使用引号引起来

3.4. secondary_check_script

MHA在连续三次检测到主库连接失败之后,如果配置文件中配置了secondary_check_script脚本,那么会调用这个脚本对主库进行再次确认主库是否真的死掉了

4、其他

4.1. 后台或daemon运行mha manager
  • 默认情况下,mha manager程序运行在前台,你可以像下面这样把程序运行在后台:
nohup masterha_manager --conf=/etc/app1.cnf < /dev/null > /var/log/masterha/app1/app1.log 2>&1 &
  • 使用daemontools工具把mha manager作为一个daemon运行
    当前mha manager不作为一个daemon运行,如果故障转移成功或者说master进程被意外地杀死,这个manager程序将停止工作,可以使用外部的daemon程序把manager程序作为daemon运行,具体配置过程如下(针对redhat发行版的安装过程):
  • 安装daemontools
yum install daemontools -y
  • 在/service/masterha(app_name)/run目录下创建运行文件
mkdir /service/masterha_app1
cat /service/masterha_app1/run
#!/bin/sh
exec masterha_manager --conf=/etc/app1.cnf --wait_on_monitor_error=60 --wait_on_failover_error=60 >> /var/log/masterha/app1/app1.log 2>&1
chmod 755 /service/masterha_app1/run
  • 通过如下命令来停止或重启daemontool 的监控命令
停止监控:
svc -d /service/masterha_app1
开始监控:
svc -u /service/masterha_app1
4.2. 运行多个mha manager程序

如果你需要在同一个mha manager服务器上监控对多主从架构,那么只需要创建一个新的配置文件,然后使用命令masterha_manager 跟上新的配置文件启动监控程序即可,如下:

masterha_manager --conf=/etc/conf/masterha/app1.cnf
masterha_manager --conf=/etc/conf/masterha/app2.cnf

此时,如果你在两对主从配置文件中有一些相同的参数,那么推荐把这些相同的参数放到全局配置文件中。

4.3. 与集群软件结合

如果你在master上使用了VIP,那么可能你已经使用了集群软件了,如果你熟悉目前的集群管理工具,那么你可能也需要使用这个集群工具来管理VIP,而不是什么事情都在MHA里来做,MHA只使用在非交互式的故障转移中,所以可以使用集群软件结合MHA来做master的故障转移,让集群软件来管理VIP。MHA重点做提升一个新主库以及修复与从库的数据一致性的工作。
以下是一个heartbeat 软件节点配置示例:

/etc/ha.d/haresources on host2
host2  failover_start  IPaddr::192.168.0.3
  • 故障转移脚本示例
start)
masterha_master_switch --master_state=dead --interactive=0 --wait_on_failover_error=0 --dead_master_host=host1 --new_master_host=host2
exit
stop)
do nothing
  • application配置文件示例
[server1]
hostname=host1
candidate_master=1

[server2]
hostname=host2
candidate_master=1

[server3]
hostname=host3
no_master=1

因为数据文件不共享,数据资源不需要被集群软件或者DRDB管理,为此,集群管理软件只是调用masterha_master_switch 脚本和接管VIP,当然,你也可以自己写一个脚本来做这个事情。

4.4. FAQ内容摘录
4.4.1. FAQ
  • 支持mysql5.0及其更高的版本,支持5.6+的系统表复制信息(relay log pos系统表)
  • 支持所有的linux发行版,也可以工作在UNIX平台(但没有经过测试),不支持WINDOWS
  • master的binlog file和pos在slave的relay log中有写,所以从slave的relay log中MHA可以精准地识别、解析出对应主库的位置
  • MHA在做故障转移的时候,会判断所有从库是否存活,如果不是,那么MHA将拒绝故障转移操作(从库不是alive的情况包括:从库无法通过连接mysql时;SQL线程因为报错而停止时;不能通过ssh连接从库时,因为要获取差异日志)
  • 在master执行load data加载大量数据时,且binlog格式是statement,那么,如果主库此时crash了,从库在恢复时可能会失败,基于语句级别的复制在Mysql中不推荐,所以最好不要使用。
  • MHA需要使用OS系统帐号来读取MySQL的binlog和relay log,如果能提供OS系统帐号权限,那么可以在云上使用MHA,MHA不依赖VIP,所以就算供应商不提供额外的VIP也可以使用MHA
  • 在以下三种情况下,MHA也不会进行故障转移操作
  • 所有节点之间的复制过滤规则不相同
  • 上一次故障转移失败,故障转移失败的日志文件会写在工作目录下,你需要移除它并手动重启故障转移
  • 上一次故障转移的时间离现在太近(在多少时间之内),默认是8个小时,可以通过参数 --last_failover_minute=(minute))来设置这个时间,在这个场景下,MHA不进行故障转移是因为高频转移失败,MHA判定通过故障转移并不能解决这个问题
  • 哪些host不会被选择为新主库?
  • 在配置文件中设置了no_master=1的
  • log-bin功能没有打开的
  • 所有slave的mysql版本不能低于5.0
  • SQL线程复制显著延迟的,如果Relay_Master_Log_File 落后与Master_Log_File ,或者说Exec_Master_Log_Pos 落后于Read_Master_Log_Pos 大于100,000,000,MHA就判定目标slave已经显著延迟
  • 哪些host会被选择为新主库?
  • 如果在配置文件中设置了candidate_master=1的,将被优先提升为新主库,然后再在这些优先的slave中看看是否有接收到最新的binlog,如果有多个slave都接收到了最新的binlog(即被判定为latest slave),在这种情况下,MHA将按照在配置文件中配置的顺序来选择最终谁为新主库
  • 如果在配置文件中,没有任何主机设置candidate_master=1,那么接受到最新的binlog 的slave被选择为新主库,如果多个从库都接收到了最新的binlog,那么就按照配置文件中的顺序来选择新主库。
  • 如果接收到最新的binlog的slave中,没有可以作为新主库的,那么将从non-latest slave(即并不是最新binlog的slave)中选择,如果non-latest slave也有多个,也将按照配置文件中的顺序来选择新主库
  • 如果在配置文件中设置了 latest_priority=0,那么是否是latest slave(是否接收到最新的binlog)就没有关系了,所有的slave都参与选择新主库,那么你就可以在配置文件中使用配置顺序来控制主机被提升为新主库的优先级
  • 如何做mha manager自身的高可用?当前针对同一个master的监控,MHA还不支持多个mha manager,所以,如果mha manager自己挂了,那么自动故障转移就没有办法进行,这个是比较严峻的问题,但是你也许又想要mha manager自身尽可能地实现高可用,那么推荐通过使用mha manager的HA active/standby方案来实现
  • 当添加/移除MySQL实例的时候,需要做什么?需要手动更新application配置文件,然后重启mha manager,如果你不想手动去修改配置文件,你可以使用masterha_conf_host工具
  • 怎么在配置文件中设置master?你不需要在配置文件中去设置master,MHA连接配置文件中所有的主机并自动判断当前的master是谁
  • 执行故障转移的时候调用purge_relay_logs会不会把relay log给清理掉?这种情况永远不会发生,因为在故障转移开始时,就会先在所有从库上加咨询锁,而这个清理工具也需要获得相同的锁才能执行清理操作。所以,在故障转移的时候,这个命令是无法获得需要的锁,所以就无法执行。
4.5.2. 常见错误以及修复方法
  • mha node包在mysql实例上没有安装,以下示例中,host2没有安装mha node的包,报如下错误:
...
Sat Jul 2 13:24:25 2011 - [info] Checking MHA Node version..
Sat Jul 2 13:24:25 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/ManagerUtil.pm, ln114] Got error when getting node version. Error:
Sat Jul 2 13:24:25 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/ManagerUtil.pm, ln115]
bash: apply_diff_relay_logs: command not found
Sat Jul 2 13:24:25 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/ManagerUtil.pm, ln130] node version on host2 not found! Maybe MHA Node package is not installed?
 at /usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm line 276
Sat Jul 2 13:24:25 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln316] Error happend while checking configurations. Died at /usr/lib/perl5/site_perl/5.8.5/MHA/ManagerUtil.pm line 131.
Sat Jul 2 13:24:25 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln397] Error happened while monitoring servers.
Sat Jul 2 13:24:25 2011 - [info] Got exit code 1 (Not master dead).
Died at /usr/bin/masterha_manager line 59.
  • 找不到master的binlog在哪里,在下面的示例中,没有使用master_binlog_dir 参数在配置文件中指定master的binlog存放路径,如果你的master的路径不是rpm发行包下的标准路径( /var/lib/mysql,/var/log/mysql),就会报如下错误:
Sat Jul 3 20:03:40 2011 - [info] Checking MHA Node version..
Sat Jul 3 20:03:41 2011 - [info]  Version check ok.
Sat Jul 3 20:03:41 2011 - [info] Checking SSH publickey authentication and checking recovery script configurations on the current master..
Sat Jul 3 20:03:41 2011 - [info]   Executing command: save_binary_logs --command=test --start_file=binlog.000002 --start_pos=4 --binlog_dir=/var/lib/mysql,/var/log/mysql --output_file=/var/tmp/save_binary_logs_test --manager_version=0.50
Sat Jul 3 20:03:41 2011 - [info]   Connecting to root@hostx(192.168.0.1)..
Failed to save binary log: Binlog not found from /var/lib/mysql,/var/log/mysql!
 at /usr/bin/save_binary_logs line 95
        eval {...} called at /usr/bin/save_binary_logs line 59
        main::main() called at /usr/bin/save_binary_logs line 55
Sat Jul 3 20:03:41 2011 - [error][/usr/lib/perl5/site_perl/5.8.8/MHA/MasterMonitor.pm, ln94] Master setting check failed!
Sat Jul 3 20:03:41 2011 - [error][/usr/lib/perl5/site_perl/5.8.8/MHA/MasterMonitor.pm, ln296] Master configuration failed.
Sat Jul 3 20:03:41 2011 - [error][/usr/lib/perl5/site_perl/5.8.8/MHA/MasterMonitor.pm, ln316] Error happend on checking configurations.  at /usr/bin/masterha_manager line 50
  • 没有权限读取binlog/relay log的目录,如果你在配置文件中指定的ssh_user用户没有权限访问binlgo/relay log的目录,就会报如下错误(建议使用高权限的用户,如root用户作为SSH连接用户):
...
Sat Jul 2 13:27:21 2011 - [info] Checking SSH publickey authentication and checking recovery script configurations on the current master..
Sat Jul 2 13:27:21 2011 - [info]   Executing command: save_binary_logs --command=test --start_file=mysqld-bin.000001 --start_pos=4 --binlog_dir=/var/lib/mysql --output_file=/var/log/masterha/save_binary_logs_test --manager_version=0.50
Sat Jul 2 13:27:21 2011 - [info]   Connecting to app@host1(host1)..
Failed to save binary log: Permission denied:/var/lib/mysql/mysqld-bin.000001
 at /usr/bin/save_binary_logs line 96
Sat Jul 2 13:27:21 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln94] Master setting check failed!
Sat Jul 2 13:27:21 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln296] Master configuration failed.
Sat Jul 2 13:27:21 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln316] Error happend while checking configurations.  at /usr/bin/masterha_manager line 50
Sat Jul 2 13:27:21 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln397] Error happened while monitoring servers.
Sat Jul 2 13:27:21 2011 - [info] Got exit code 1 (Not master dead).
Died at /usr/bin/masterha_manager line 59.
  • 使用了多主复制(默认情况下,所有的从库需要配置成从相同的主库上复制),MHA不支持,就会报如下错误:
...
Sat Jul 2 13:23:14 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/ServerManager.pm, ln522] FATAL: Replication configuration error. All slaves should replicate from the same master.
Sat Jul 2 13:23:14 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/ServerManager.pm, ln1066] MySQL master is not correctly configured. Check master/slave settings
Sat Jul 2 13:23:14 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln316] Error happend while checking configurations.  at /usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm line 243
Sat Jul 2 13:23:14 2011 - [error][/usr/lib/perl5/site_perl/5.8.5/MHA/MasterMonitor.pm, ln397] Error happened while monitoring servers.
Sat Jul 2 13:23:14 2011 - [info] Got exit code 1 (Not master dead).
Died at /usr/bin/masterha_manager line 59.
4.6. MHA内部如何工作
4.6.1. 如何确定从中继日志的什么位置开始应用?
  • 很久以前,MHA使用mysqlbinlog来识别relay log的位置,现在,MHA不使用mysqlbinlog,而是使用解析binlog的头部信息的方法来识别位置

  • 使用解析自己binlog头部代替mysqlbinlog解析的原因是,mysqlbinlog解析的方法有些问题,最大的原因是因为mysqlbinlog没有一个选项使他只打印binlog的头部信息,它总是打印binlog的内容主体部分

  • 要识别relay log的位置,所有必要的信息(binlog event type,server id,event length,end log pos)都保存在binlog的头部信息当中,所以不需要去解析binlog的内容主体部分,mysqlbinlog不仅增加了读取binlog数据的性能开销,而且我们还需要关心某些类型的SQL语句,因为基于SQL语句的binlog在内容主体里边可能包含了一些位置信息。

  • 快速查找relay log的位置

  • 假如目标master(需要恢复的slave)的log file:pos is mysqld-bin.000001:504810023,latest master的log file:pos is mysqld-bin.000001:504810689,latest relay log的og file is mysqld-relay-bin.000001以及文件大小大于500M,但是这两个位置信息之差仅仅只占用666个字节,如果MHA解析整个relay log,就是500M的大小,需要耗费比较长的时间,也就是说,需要耗费比较长的时间来恢复数据,造成长时间的down机,所以,MHA并不总是从开头扫描relay log,也会从差异的位置开始扫描,基于如下扫描规则:

$latest_mlf = Master_Log_File on the latest slave
  $target_mlf = Master_Log_File on the recovery target slave
  $latest_rmlp = Read_Master_Log_Pos on the latest slave 
  $target_rmlp = Read_Master_Log_Pos on the recovery target slave
  $offset = $latest_rmlp - $target_rmlp
  $filesize = File size of the latest relay log file on the latest slave
如果$latest_mlf等于$target_mlf and $filesize > $offset,and 如果binlog event可以从$filesize - $offset这个位置读取到(其实这个相当于从relay log的末尾倒推),MHA就决定开始从lasest slave的relay log中的($filesize - $offset) 这个位置开始恢复,这样就避免了扫描巨大的relay log文件,提高扫描的速度。
4.6.2. 怎样生成应用到目标slave的SQL语句?
  • MHA处理这部分逻辑算法现在是(三个步骤生成一个二进制日志文件,文件名默认为/var/tmp/aggregate.binlog):

  • 把目标slave(需要恢复数据的slave)的从exec pos到read pos位置的binlog的内容从relay log中提取出来(这里没有经过mysqlbinlog解析,而是直接读的原始的二进制格式日志),生成/var/tmp/aggregate.binlog文件

  • 把从目标slave的read pos到最新的latest slave的read pos之间的binlog内容从latest slave的relay log中提取出来,去掉每一个relay log的Format_description_event(一个日志文件只能有一个FDE,所以第二个步骤要去掉FDE),并合并到/var/tmp/aggregate.binlog里

  • 把从最新的latest slave的read pos到master的最后一个日志尾之间binlog的内容提取出来,去掉每一个binlog的FDE,并合并到/var/tmp/aggregate.binlog里

  • 执行mysqlbinlog命令来解析这个合成的二进制日志文件,并通过mysql命令应用到目标slave中

  • PS:加一点自己的理解,纵观MHA整个故障转移过程来说,上面第三步提取master的日志其实是在补偿新主库的阶段就先提取过了,然后放到了mha manager上,在恢复从库的阶段,只是在第三步的时候,把这个差异日志从mha manager上复制过来,并合并到/var/tmp/aggregate.binlog里(没有去研究源码,只是个人的理解),要注意的是,前面三个提取二进制日志的步骤顺序不能乱,乱了数据就乱了

  • 逻辑变更的原因如下:

  • 为了支持基于row格式的binlog event:当前mysqlbinlog不能够准确地打印一个有效的SQL语句,除非基于row格式的整个event都写在了一个log file里,例如:如果部分event(TABLE_MAP_EVENT event) 写在了mysqld-relay-bin.000001 ,剩下一部分event(WRITE_ROWS events) 写在了 mysqld-relay-bin.000002,那么mysqlbinlog打印一个有效的基于row格式的event,所以原始的方案(合并多个mysqlbinlgo命令的输出)在基于row格式时并不总是能正常工作, 新的方案适用于语句和row格式,因为mysqlbinlog需要解析的对象是经过合并的单个log file。

  • mysqlbinlog隐式地在输出内容的尾部添加rollback语句,有些时候在每一个binlog file的开头也存在,这样rollback语句需要修剪,以避免局部事务回滚,解析所有mysqlbinlog输出、替换目标rollback语句以及等效BINLOG语句,但是解析所有的输出会增加开销,新的方案只需要解析单个日志,只返回一次rollback语句,不需要添加中间事务。所以,MHA创建单个大的binlog file来应用到每一个目标从库,当需要合并多个relay/binary log的时候,MHA裁剪掉除了第一个日志之外其他日志的format description events,裁剪这个的原因是mysqlbinlog解析这个日志的时候,多余的format description events可能会产生一些不必要的rollback语句

5、mha的配置文件参数详解

  • 配置参数详解:


作用域范围解释: Local Scope 表示可以设置在单个app配置文件中的[server_xx]块标记下边的参数;App Scope表示可以针对单个app内所有的master和slave设置,可以设置在单个app配置文件中的[server_default]块标记下边;Global Scope表示全局参数,可以设置在全局配置文件中

  • 以下是配置文件中具体每个配置参数的解释:

  • hostname:目标实例的主机名或者IP地址,这个参数是强制的,只能配置在app配置文件的[server_xxx]段落标记下

  • ip:目标实例的ip地址,默认从hostname获取,MHA内部管理节点与数据节点之间的mysql和ssh通过这个IP连接,正常情况下你不需要配置这个参数,因为MHA会自动解析Hostname获得

  • port:目标实例的端口,默认是3306,MHA使用mysql server的IP和port连接

  • ssh_host:从0.53版本开始支持,默认情况下和hostname参数相同,当你使用了VLAN隔离的时候,比如为了安全,把ssh网段和访问数据库实例的网段分开使用两个不同的IP,那么就需要单独配置这个参数

  • ssh_ip:从0.53版本开始支持,默认情况下与ssh_host相同

  • ssh_port:从0.53版本开始支持,目标数据库的ssh端口,默认是22

  • ssh_connection_timeout:从0.54版本开始支持,默认是5秒,增加这个参数之前这个超时时间是写死在代码里的

  • ssh_options:从0.53版本开始支持,额外的ssh命令行选项

  • candidate_master:从不同的从库服务器中,提升一个可靠的机器为新主库,(比如:RAID 10比RAID0的从库更可靠),可以通过在配置文件中对应的从库服务器的配置段下添加candidate_master=1来提升这个从库被提升为新主库的优先级(这个从库要开始binlog,以及没有显著的复制延迟,如果不满足这两个条件,也并不会在主库挂掉的时候成为新主库,所以,这个参数只是提升了优先级,并不是说指定了这个参数就一定会成为新主库)

  • no_master:通过在目标服务器的配置段落设置no_master=1,它永远也不会变为新主库,用于配置在不想用于接管主库故障的从库上,如:只是一个binlog server,或者硬件配置比较差的从库上,或者这个从库只是一个远程灾备的从库,但是,要注意,不能把所有的从库都配置这个参数,这样MHA检测到没有可用备主的时候,会中断故障转移操作

  • ignore_fail:默认情况下,MHA在做故障转移的时候,会去检测所有的server,如果发现有任何的从库有问题(比如不能通过SSH检测主机或者mysql的存活,或者说有SQL线程复制错误等)就不会进行故障转移操作,但是,有时候可能需要在特定从库有故障的情况下,仍然继续进行故障转移,就可以使用这个参数指定它。默认是0,需要设置时在对应服务器的配置段下添加ignore_fail=1

  • skip_init_ssh_check:监控程序启动的时候,跳过SSH连接检测 * skip_reset_slave:0.56开始支持,master故障转移之后,跳过执行reset slave all语句 * user:目标mysql实例的管理帐号,尽量是root用户,因为运行所有的管理命令(如:stop slave,change master,reset slave)需要使用,默认是root

  • password:user参数指定的用户的密码,默认为空

  • repl_user:在所有slave上执行change master的复制用户名,这个用户最好是在主库上拥有replication slave权限

  • repl_password:repl_user参数指定的用户的密码,默认情况下,是当前复制帐号的密码,如果你运行了online master switch脚本且使用了--orig_master_is_new_slave做在线切换,当前主库作为了从库加入新主库,此时,如果你没有设置repl_password来指定复制帐号的密码,当前主库作为从库加入新主库的时候会在change master的时候失败,因为默认情况下这个密码是空的,MHA做切换的时候,其他所有作为从库加入新主库时,都需要使用这个密码

  • disable_log_bin:如果设置这个参数,当应用差异日志到从库时,slave不生成binlog写入,内部通过mysqlbinlog命令的--disable-log-bin选项实现

  • master_pid_file:设置master的pid,在运行多实例的环境下,你可能需要用到这个参数来指定master的pid,参考shutdown_script参数详解

  • ssh_user:访问MHA manger和MHA mysql节点的OS系统帐号,需要使用它来远程执行各种各样的管理mysql节点的命令(从manager到mysql),从latest slave拷贝差异日志到其他从库上(从mysql到mysql),该用户必须要能够没有任何交互地连接到服务器,通常使用ssh key认证,默认情况下,这个用户是manager所在的OS系统用户。

  • remote_workdir:每一个MHA node(指的是mysql server节点)生成日志文件的工作路径,这个路径是绝对路径,如果该路径目录不存在,则会自动创建,如果没有权限访问这个路径,那么MHA将终止后续过程,另外,你需要关心一下这个路径下的文件系统是否有足够的磁盘空间,默认值是/var/tmp

  • master_binlog_dir:在master上生成binlog的绝对路径,这个参数用在master挂了,但是ssh还可达的时候,从主库的这个路径下读取和复制必须的binlog events,这个参数是必须的,因为master的mysqld挂掉之后,没有办法自动识别master的binlog存放目录。默认情况下,master_binlog_dir的值是/var/lib/mysql,/var/log/mysql,/var/lib/mysql目录是大多数mysql分支默认的binlog输出目录,而 /var/log/mysql是ubuntu包的默认binlog输出目录,这个参数可以设置多个值,用逗号隔开

  • log_level:manager记录日志的等级,默认以及大多数场景下都是info级别,可以设置的值为debug/info/warning/error

  • manager_workdir:mha manager生成的相关状态文件的绝对路径,如果没有设置,则默认使用/var/tmp

  • client_bindir: 如果mysql命令工具是安装在非标准路径下,那么使用这个参数指定绝对路径

  • client_libdir:如果mysql的库文件是安装在非标准路径下,那么使用这个参数指定据对路径

  • manager_log:mha manager生成的日志据对路径,如果没有设置,mha manager将打印在标准输出,标准错误输出上,如:当mha manager执行故障转移的时候,这些信息就会打印

  • check_repl_delay:默认情况下,如果从库落后主库100M的relay logs,MHA不会选择这个从库作为新主库,因为它会增加恢复的时间,设置这个参数为0,MHA在选择新主库的时候,则忽略复制延迟,这个选项用在你使用candidate_master=1 明确指定需要哪个从库作为新主库的时候使用。

  • check_repl_filter:默认情况下,如果master和slave相互之间有任何不同的binlog复制过滤规则,MHA将打印错误日志并拒绝启动监控程序或者拒绝故障转移操作,这是为了避免意外出现类似Table not exists这样的错误,如果你100%确定不同的复制过滤规则不会出现恢复问题,那么就设置check_repl_filter = 0,此时MHA在应用差异日志的时候就不会去检测复制过滤规则,但是你可能会碰到Table not exists这样的错误,使用这个参数要非常小心

  • latest_priority:默认情况下,latest slave(收到最新的binlog的slave),优先作为新主库,如果你想控制这个优先级顺序,可以通过 latest_priority=0,此时,就会按照配置文件中配置的顺序来选择新主库(如 host2->host3->host4)。

  • multi_tier_slave:从0.52版本开始,支持多个主库的复制架构,默认情况下,在配置文件中不支持三个或更多层级的复制架构,例如:host2从host1复制,host3从host2复制,默认情况下,是不允许host1,2,3同时可写的。因为这个是一个三层复制,MHA manager会报错并停止,设置这个参数之后,MHA manager不会中断三层复制架构的监控,只是忽略了第三层,即host3,如果host1挂了,host2将接管host1,被选择为新主库,host3继续从host3复制。

  • ping_interval:这个参数表示mha manager多久ping(执行select ping sql语句)一次master,连续三个丢失ping连接,mha master就判定mater死了,因此,通过4次ping间隔的最大时间的机制来发现故障,默认是3,表示间隔是3秒

  • ping_type:从0.53版本开始支持,默认情况下,mha master基于一个到master的已经存在的连接执行select 1(ping_type=select)语句来检查master的可用性,但是在有些场景下,最好是每次通过新建/断开连接的方式来检测,因为这能够更严格以及更快速地发现TCP连接级别的故障,把ping_type设置为connect就可以实现。从0.56开始新增了ping_type=INSERT类型。

  • secondary_check_script:通常,推荐通过两个或者更多的网络路径来检测master的可用性,默认情况下,MHA只是通过单个网络路径来检测,即从mha master到master的路线,但是不推荐这么做,mha可以通过secondary_check_script 参数来调用一个外部的脚本来实现两个或更多个网络路径来检测master的可用性,配置示例如下:
    secondary_check_script = masterha_secondary_check -s remote_host1 -s remote_host2
    masterha_secondary_check 脚本包含在mha manager的安装包里,这个脚本适合大多数的场景,但是你可以调用任何你自定义的脚本。
    在上述的示例中,mha manager检测master的存活的网络路径是:mha manager-->remote_host1-->master_host和mha manager-->remote_host2-->master_host,如果两条线路中,mha master到远程主机的连接是通的,但是远程主机到master不通,这个脚本返回状态0,那么mha就判定master死了。 将开始执行故障转移。如果mha manager到远程主机都不通,那么这个脚本返回状态2,mha manager就猜测网络可能发生了问题了,拒绝执行故障转移操作。如果两条线路从头到位都走通了,那么这个脚本返回状态3,此时mha master知道主库是或者的,就不会进行故障转移操作。
    通常来说,remote_host1和remote_host2需要处于本地的两个不同的网段
    mha调用secondary_check_script 脚本自动地传递如下参数(不需要你在配置文件中的secondary_check_script 参数中指定这些参数),如果你需要更多的功能,你可以自定义这个脚本:
    --user:远程主机ssh用户名,如果指定了这个,那么ssh_user参数就会被忽略
    --master_host:指定master的主机名(实例)
    --master_ip:指定master的IP(实例)
    --master_port:指定master的端口号(实例)
    PS:运行这个脚本需要依赖perl的 IO::Socket::INET包,这个包包含在perl的5.6.0里,masterha_secondary_check 脚本仍然通过免密钥的ssh来连接远程服务器,这个脚本尝试从远程服务器建立到master的TCP连接,这个意思是my.cnf中的max_connections 参数对这个么有 影响,如果这个TCP连接成功了,在mysql的Aborted_connects 变量中会增加1

  • master_ip_failover_script:通常在MHA环境下,通常需要分配一个VIP供master用于对外提供读写服务,如果master挂了,HA软件指引备用服务器接管VIP,另外一个通用的方法,是在数据库中创建一个全局的应用程序名称与读写IP地址之间的全局类目映射( {app1_master1, 192.168.0.1}, {app_master2, 192.168.0.2}, …)来代替VIP地址的使用,在这种情况下,如果你的master挂了,你需要更新这个数据库中的全局类目映射。第二种方法这里个人觉得跟智能DNS解析类似。
    两种方法各有优缺点,MHA不强制使用哪一种方法,但是允许用户使用任何IP地址做故障转移的方案,master_ip_failover_script 参数可以用于实现这个目的,换句话说,你需要自己编写一个脚本来透明地把应用程序连接到新主库上。需要在配置文件中定义这个参数,示例如下:
    master_ip_failover_script= /usr/local/sample/bin/master_ip_failover
    mha manager安装包中(tar包和githup分支上才有,rpm包没有)的samples/scripts/master_ip_failover路径下有一个简单的脚本
    mha manager会调用master_ip_failover_script 这个参数指定的脚本三次,第一次是在进入主库监控之前(为了检测脚本的有效性),第二次是将要调用shutdown_script参数的脚本之前,第三次是新主库应用完成了差异relay log之后,mha manager调用这个脚本会用到如下参数(注意:你不需要在配置文件中这个参数上单独设置这些)
    检测阶段参数:
    --command=status
    --ssh_user=(current master's ssh username)
    --orig_master_host=(current master's hostname)
    --orig_master_ip=(current master's ip address)
    --orig_master_port=(current master's port number)
    关闭当前master的阶段参数(注意,到调用shutdown_script的时候,主库已经被判定为死了):
    --command=stop or stopssh
    --ssh_user=(dead master's ssh username, if reachable via ssh)
    --orig_master_host=(current(dead) master's hostname)
    --orig_master_ip=(current(dead) master's ip address)
    --orig_master_port=(current(dead) master's port number)
    新的master激活阶段参数:
    --command=start
    --ssh_user=(new master's ssh username)
    --orig_master_host=(dead master's hostname)
    --orig_master_ip=(dead master's ip address)
    --orig_master_port=(dead master's port number)
    --new_master_host=(new master's hostname)
    --new_master_ip=(new master's ip address)
    --new_master_port(new master's port number)
    --new_master_user=(new master's user)
    --new_master_password(new master's password)
    如果你在master上使用的是共享VIP,那么在master的shutdown阶段就不需要做任何事情,只要在shutdown_script脚本关闭机器的电源之后,在新的master的激活阶段,在新的master上分配这个VIP即可,如果你使用的是一个全局类目映射的方案,你可能需要在shutdown死掉的master阶段之后,删除或者更新对应的dead master的记录。在新的master的激活阶段,你可以新增或者更新对应的新的master的记录,然后,你可以做一些事情(如:在新主库上执行set global read_only=0;以及创建数据库用户的写权限),以便应用程序就可以在新的主库上写入数据了
    mha manager会检测脚本执行退出的代号,如果是0或者10,mha manager则继续操作,如果返回的是0和10以外的代号,mha manager停止并中断故障转移,默认情况下,这个参数为空,所以,默认情况下mha不会调用这个脚本做任何事情。

  • master_ip_online_change_script:这是一个与master_ip_failover_script 参数很接近的参数,但是这个参数不使用故障转移命令,而是master的在线change命令(masterha_master_switch --master_state=alive),使用如下参数(注意:你不需要在配置文件中这个参数上单独设置这些):
    冻结当前主库写操作阶段的参数:
    --command=stop or stopssh
    --orig_master_host=(current master's hostname)
    --orig_master_ip=(current master's ip address)
    --orig_master_port=(current master's port number)
    --orig_master_user=(current master's user)
    --orig_master_password=(current master's password)
    --orig_master_ssh_user=(from 0.56, current master's ssh user)
    --orig_master_is_new_slave=(from 0.56, notifying whether the orig master will be new slave or not)
    允许新的主库写阶段的参数:
    --command=start
    --orig_master_host=(orig master's hostname)
    --orig_master_ip=(orig master's ip address)
    --orig_master_port=(orig master's port number)
    --new_master_host=(new master's hostname)
    --new_master_ip=(new master's ip address)
    --new_master_port(new master's port number)
    --new_master_user=(new master's user)
    --new_master_password=(new master's password)
    --new_master_ssh_user=(from 0.56, new master's ssh user)
    在冻结当前主库写的阶段,mha manager在当前主库上执行FLUSH TABLES WITH READ LOCK,你可以写任何的逻辑来优雅地实现主库的切换(参考http://www.slideshare.net/matsunobu/automated-master-failover/44),在新的master允许写的阶段,你可以做和master_ip_failover_script脚本的第三阶段几乎一样的事情,例如:在新的主库上创建写权限用户和执行set global read_only=0语句,或者更新全局类目映射记录,如果这个脚本执行返回状态吗是0或者10以外的值,mha manager将终止并停止master在线切换操作。默认这个参数为空,mha不会调用这个参数做任何事情,在mha manager的tar包和githup分支下的samples/scripts/master_ip_online_change路径下有一个简单的脚本。

  • shutdown_script:你可能想要强制关闭master节点来避免master节点重新启动服务,这对于避免脑裂来说是很重要的,示例:
    shutdown_script= /usr/local/sample/bin/power_manager
    在mha manager的tar包和github的分支的samples/scripts/power_manager路径下有一个简单的脚本,在调用这个脚本之前,mha manager内部会通过ssh去检测master是否可达,如果ssh可达(主机OS活着但是mysqld挂了),mha manager使用如下参数:
    --command=stopssh
    --ssh_user=(ssh username so that you can connect to the master)
    --host=(master's hostname)
    --ip=(master's ip address)
    --port=(master's port number)
    --pid_file=(master's pid file)
    如果master通过ssh不可达,那么mha manager就会使用如下参数:
    --command=stop
    --host=(master's hostname)
    --ip=(master's ip address)
    这个脚本工作流程如下:
    如果通过--command=stopssh参数,这个脚本通过ssh过去master上kill -9杀掉mysqld和mysqld_safe进程,如果同时也通过--pid_file参数,这个脚本通过ssh过去主库上只kill -9杀掉指定的进程号,不会杀掉所有的进程,这个对在master上运行多实例的时候有帮助,如果通过ssh停止成功,这个脚本退出状态是10,如果退出状态是10,mha manager随后就通过ssh连接到master保存必要的binlog,如果这个脚本通过ssh连接master失败,或者mha manager是使用的参数 --command=stop,这个脚本就会尝试关闭机器的电源,关闭机器的命令依赖硬件(For HP(iLO), 通常是ipmitool or SSL,For Dell(DRAC), 通常是dracadm),如果关闭电源成功,这个脚本的退出状态是0,否则退出的状态是1,如果这个脚本的退出状态是0,则mha manager开始执行故障转移过程,如果这个状态是0和10以外的其他状态,则mha终止故障转移,默认这个参数为空,所以mha不会调用这个参数做任何事情。
    另外,mha manager开始监控的时候会调用shutdown_script 参数,在这次调用会使用以下参数,在这里可以检测脚本的设置,控制电源需要高度依赖硬件,所以建议要检测电源的状态,如果发现什么问题,你可以在启动监控程序之前去解决。
    --command=status
    --host=(master's hostname)
    --ip=(master's ip address)

  • report_script:在故障转移完成或者说因为错误而终止的时候,你可能希望发送一个报告出来,这就是使用report_script 参数的目的,mha manager通过如下参数使用这个脚本:
    --orig_master_host=(dead master's hostname)
    --new_master_host=(new master's hostname)
    --new_slave_hosts=(new slaves' hostnames, delimited by commas)
    --subject=(mail subject)
    --body=(body)
    默认情况下,这个参数是空的,mha manager不会调用这个参数做任何事情,在mha manager的tar包和github分支的samples/scripts/send_report路径下有一个简单的脚本。

  • init_conf_load_script:这个脚本在你不想在配置文件中设置纯文本的信息的时候使用(比如:password和repl_password),从这个脚本返回name=value的键值对,它可以作为全局配置文件参数,示例脚本内容如下:

#!/usr/bin/perl
print "password=$ROOT_PASS\n";
print "repl_password=$REPL_PASS\n";

这个参数默认为空,所以mha manager不会调用这个参数做任何事情

6、mha注意事项

  • MHA的选举出latest slave之后,对于non-latest slaves从库之间补日志是并行的,所以,如果从库超过10个,可能会出现部分slave恢复失败的情况,因为ssh默认的配置是10个并发连接,需要修改 /etc/ssh/sshd_config中的MaxStartups变量为大于10的值,官网原文如下:
    MHA Manager internally executes recovery in parallel. When generating differential relay log files, MHA connects to the latest slave via SSH in parallel and generates and sends differential relay logs to non-latest slaves. If you have tens of slaves or consolidate tens of MySQL instances within single OS, sshd might reject SSH connection requests, which will cause slave recovery errors. To avoid this issue, raise MaxStartups parameter in /etc/ssh/sshd_config (default 10) and restart sshd.

  • MHA不支持串行复制结构,如:master1->master2->slave3,不支持slave3的监控和数据恢复,只支持master1和master2之间的故障切换,所以,MHA中要使用双主,只能是master1->(master2,slave3)的并行复制结构,官网原文如下:
    MHA does not support three or more tier replication structure by default(i.e. Master1 -> Master2 -> Slave3). MHA does failover and recover only slaves that directly replicate from the current primary master. MHA can manage master1 and master2 and promote master2 when master1 crashes, but MHA can not monitor and recover slave3 because slave3 replicates from different master(master2). To make MHA work with such structures, either configure as below.

  • 使用mysql 5.1+版本的mysqlbinlog命令,因为这个版本之后才支持row格式,如果使用低于这个版本的,将无法解析binlog做数据恢复,官网原文如下:
    MHA uses mysqlbinlog for applying binlog events to target slaves. If the master uses row based format, row based events are written in the binary log. Such binary logs can be parsed by mysqlbinlog in MySQL 5.1 or higher only because mysqlbinlog in MySQL 5.0 does not support row based format. mysqlbinlog (and mysql) version can be checked as below.

  • 作为备用主库,一定要开启log-bin,MHA会内部检测log-bin的设置,没有开启binlog的从库将不能被提升为新主库,如果没有任何从库开启log-bin,MHA即将不会执行故障转移,官网原文如下:
    If current slaves do not set log-bin, obviously they can not be the new master. MHA Manager internally checks log-bin settings, and do not promote them to new master. If none of the current slaves set log-bin, MHA Manager does not proceed failover.

  • 所有从库的复制过滤规则必须相同,MHA启动的时候会检测复制过滤规则,如果有所有从库的过滤规则有不一样的情况,将拒绝启动、拒绝做故障转移操作,官网原文如下:
    Replication filtering rules (binlog-do-db, replicate-ignore-db, etc) must be the same on all MySQL servers. MHA checks filtering rules at startup, and doesn't start monitoring or failover if filtering rules are not same each other.

  • 作为复制的帐号,必须在主库和备用主库都存在,因为在做故障转移的时候,MHA会使用这个复制帐号让其他从库change master过来(这个复制帐号指的就是写在配置文件中的那个repl_user),个人建议所有节点帐号相同,官网原文如下:
    After master failover completes, all other slaves execute CHANGE MASTER TO statement. To start replication, a replication user (with REPLICATEION SLAVE privilege) must exist on the new master.

  • mysql默认情况下,会把sql线程重放完的relay log清理掉,但是 因为从库恢复需要用到relay log,所以需要关闭从库自动清理relay log的操作,但是有个问题需要注意,如果relay log堆积太多,而你一次性手动清理的relay log太多,可能会因为磁盘资源占用过多而导致复制延迟,所以,要么周期性的手动清理relay log,要么使用硬链接清理(使用自带的命令purge_relay_logs做清理,这个命令是使用创建硬链接的方式清理relay log),官网原文如下:
    By default, relay logs on slave servers are automatically removed if SQL threads have finished executing them. But such relay logs might still be needed for recovering other slaves. So you need to disable automatic relay log purge, and periodically purges old relay logs. But you need to care about replication delay issues when manually purging relay logs. On ext3 filesystem, removing large files takes significant time, which will cause serious replication delay. To avoid replication delay, tentatively creating hard links of the relay logs helps. See the two slides for details.
    PS:可以把这个命令放到计划任务里,做定时调用(建议在不同的从库上,调用时间错开),如:

cat /etc/cron.d/purge_relay_logs
# purge relay logs at 5am
0 5 * * * app /usr/bin/purge_relay_logs --user=root --password=PASSWORD --disable_relay_log_purge >> /var/log/masterha/purge_relay_logs.log 2>&1
  • 不要使用load data infile语句,当使用基于SBR的binlog格式在主库崩溃恢复完成之后,MHA可能无法获得relay log差异日志,另外,如果你使用了一些非事务引擎或者太老的mysql版本,会有一些已知的问题,另外,也可能导致复制延迟,官网原文如下:
    When the master is crashed just after completing LOAD DATA INFILE with Statement Based Binary Logging, MHA might not be able to generate differential relay log events, if you use non-transactional storage engine or too old MySQL version (i.e. 5.0.45, etc). Using LOAD DATA INFILE with SBR has some known issues and it's deprecated from MySQL 5.1. LOAD DATA INFILE also causes significant replication delay, so there are not positive reasons to use it.
    If you want to use LOAD DATA, SET sql_log_bin=0; LOAD DATA … ; SET sql_log_bin=1; is more recommended approach.

  • 如果使用GTID复制,那么所有节点的mysql版本必须大于等于5.6,且必须所有节点都开启GTID,至少有一个节点使用Auto_Position =1,官网原文如下:
    Starting from MHA 0.56, MHA supported both GTID based failover and traditional relay log based failover. MHA automatically distinguishes which failover to choose. To do GTID based failover, all of the following is needed.
    Using MySQL 5.6 (or later)
    All MySQL instances use gtid_mode=1
    At least one of the instances has Auto_Position enabled

posted @ 2016-10-21 14:33  xiaoboluo768  阅读(4232)  评论(0编辑  收藏  举报