一、简介学习一个高可用小软件,不但要熟悉其功能,还要了解其架构及工作原理。
1. 架构从架构上来说,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环境。
2. 工作原理相较于其它ha软件,mha的目的在于维持mysql replication中master库的高可用性,其最大特点是可以修复多个slave之间的差异日志,最终使所有slave保持数据一致,然后从中选择一个充当新的master,并将其它slave指向它。
基本工作流程大致如下:
(1) manager定期监控master,监控时间间隔由参数ping_interval决定,缺省为3秒钟一次;可利用其自身的监控功能,也可调用第三方软件来监控;mha自身提供了两种监控方式:select(执行select 1)和connect(创建连接/断开连接),由于参数ping_type决定,缺省为select方式。
(2) 当监测到master故障时,调用ssh脚本对所有node执行一次检查,包括如下几个方面:
――mysql实例是否可以连接;
――master服务器是否可以ssh连通;
――检查sql thread的状态;
――检查哪些server死掉了,哪些server是活动的,以及活动的slave实例;
――检查slave实例的配置及复制过滤规则;
――最后退出监控脚本并返回代表特殊意义代码。
(3) 开始master故障切换,包括如下几个子阶段:
――phase 1: configuration check phase
在这个阶段,若某个slave实例的sql thread停止了,则会自动启动它;并再次确认活动的servers及slaves。
――phase 2: dead master shutdown phase
在这个阶段,首先调用master_ip_failover_script,若ha是基于vip实现的,则关闭vip,若是基于目录数据库实现的,则修改映射记录。
然后调用shutdown_script脚本强制关闭主机,以避免服务重启时,发生脑裂。
――phase 3: master recovery phase
又包括如下3个子阶段:
phase 3.1: getting latest slaves phase
检查各个slave,获取最近的和最旧的binary log file和position,并检查各个slave成为master的优先级,依赖于candidate_master、no_master、[server_xxx]顺序、binary log差异量等因素。
phase 3.2: saving dead master's binlog phase
若dead master所在服务器依然可以通过ssh连通,则提取dead master的binary log,提取日志的起点就是上一步获取的最新的binary log file和position,直到最后一条事件日志,并在dead master本地的工作目录(由参数remote_workdir决定)中创建文件保存这些提取到的日志,然后将该文件拷贝到manager服务器的工作目录下(由参数manager_workdir决定)。
当然,若dead master系统就无法连接,也就不存在差异的binary log了。
另外,mha还要对各个slave节点进行健康检查,主要是ssh连通性。
phase 3.3: determining new master phase
接下来调用apply_diff_relay_logs命令恢复slave的差异日志,这个差异日志指的是各个slave之间的relay log。
恢复完成后,所有的slave数据是一致的,此时就可以根据优先级选择new master了。
phase 3.3: new master diff log generation phase
这里是生成dead master和new master之间的差异日志,即将phase 3.2保存的binary log拷贝到new master的工作目录中(remote_workdir)。
phase 3.4: master log apply phase
将上一步拷贝的差异日志恢复到new master上,若发生错误,也可手动恢复。
然后获取new master的binlog name和position,以便其它slave从这个新的binlog name和position开始复制。
最后会开启new master的写权限,即将read_only参数设置为0。
――phase 4: slaves recovery phase
phase 4.1: starting parallel slave diff log generation phase
生成slave与new slave之间的差异日志,并将该日志拷贝到各slave的工作目录下,这部分日志dead master和new master之间差异的那部分日志,因为各个slave在phase 3.3阶段已经同步了。
phase 4.2: starting parallel slave log apply phase
在各个slave上应用这部分差异日志,然后通过change master to命令将这些slave指向新的new master,最后开始复制(start slave)。
――phase 5: new master cleanup phase
清理new master其实就是重置slave info,即取消原来的slave信息。
至此整个master故障切换过程完成。
3. 功能从官方网站的介绍来看,mha具有如下几个功能:
(1) master自动监控和故障转移
基于现有的mysql主从复制环境,mha可以监控master,当发现其故障时,自动进行切换。
在多个slave环境中,如果个别slave没有接受到最新的relay log events,mha则会自动从最新的那个slave上查找差异的relay log events,并将这些差异事件应用到有延迟的slave上,最终保持所有的slave数据一致。通常情况下,mha可在9-12秒内监测到master故障,7-10秒内关闭主机以避免脑裂,然后花费几秒时间应用差异的relay log,整个过程通常只需10-30秒即可完成。
既然mha可以自动修复多个slaves之间的差异日志,所以不用担心数据一致性问题。当master故障时,mha会从多个slave中随机选择一个充当新的master;当然,也可在配置文件中指定某一个slave优先成为master。
(2) 互动(手动)master故障转移
可以只使用mha的故障转移功能,而不监控master,当其故障时,手动调用mha来进行故障切换。
(3)非交互式自动故障转移
mha还支持非交互式的master故障切换(不监控master,但实现自动故障切换),这个特性其实是将master的监控和vip接管交给第三方工具来做,比如heartbeat,mha只负责master故障转移和slave之间的数据同步。
(4) 在线切换master到不同的主机
在有些情况下,比如更换raid控制器,升级主机硬件等,则需要将其上的master实例迁移到其它主机上,mha支持快速的master切换和短暂的写操作阻塞,通常只需0.5-2秒的downtime,这是可以接受的,也方便了dba的操作。
二、搭建环境系统环境
os:centos 5.8 (x86_64) 内核:2.6.18-308.el5 db:mysql 5.5.17
hostname ip mysql role mha role
node1 192.168.3.27 master node
node2 192.168.3.28 slave1 (备用) node
node3 192.168.3.25 slave2 node
mmm 192.168.3.26 manager
1.安装mhamha的安装包也包括manager和node两部分,其中node包不但要在所有的node节点上安装,而且还需在manager节点上安装,因为manager模块内部依赖node模块,
manager包则只需在manager节点安装即可。
从mha官网http://code.google.com/p/mysql-master-ha/downloads/list下载合适的安装包,可以是源码包,也可以是rpm包,本例采用rpm包,如下:
manager包:mha4mysql-manager-0.55-1.el5.noarch.rpm
node包:mha4mysql-node-0.54-1.el5.noarch.rpm
mha是采用perl语言编写的一个脚本管理工具,所以需要安装一系列perl依赖包。
1、在所有节点上安装perl语言依赖包
# rpm -ivh mysql-shared-compat-5.5.17-1.rhel5.x86_64.rpm
# rpm -ivh perl-dbi-1.52-2.el5.x86_64.rpm
# rpm -ivh perl-dbd-mysql-3.0007-2.el5.x86_64.rpm
(以下依赖包为manager节点需要)
# rpm -ivh perl-params-validate-0.95-1.el5.rf.x86_64.rpm
# rpm -ivh perl-log-dispatch-2.26-1.el5.rf.noarch.rpm
# rpm -ivh perl-config-tiny-2.12-1.el5.rf.noarch.rpm
# rpm -ivh perl-parallel-forkmanager-0.7.5-2.2.el5.rf.noarch.rpm
在所有节点及manager上安装node包
# rpm -ivh mha4mysql-node-0.54-1.el5.noarch.rpm
在manager节点上安装manager包
# rpm -ivh mha4mysql-manager-0.55-1.el5.noarch.rpm
成功安装后,会在/usr/bin目录下生成如下一系列命令工具:
/usr/bin/masterha_check_repl
/usr/bin/masterha_conf_host
/usr/bin/masterha_master_switch
/usr/bin/masterha_check_ssh
/usr/bin/masterha_manager
/usr/bin/masterha_secondary_check
/usr/bin/masterha_check_status
/usr/bin/masterha_master_monitor
/usr/bin/masterha_stop
2.配置mha接下来就可以配置mha配置文件了,只需在manager服务器上操作;rpm包安装时,缺省不会生成该配置文件,可手动生成,也可从mha manager源码安装包中查找配置文件模板,及一系列调用脚本。
创建工作目录
在node上创建一个单独的工作目录,用于remote_workdir参数来存放相关日志文件,缺省为/var/tmp,若未创建,mha也会自动创建,但这需要有创建权限。
# mkdir -p /mha/appl
在manager上创建工作目录,用于manager_workdir参数,其中存放日志文件和一系列脚本文件等。
# mkdir -p /mha/appl
# mkdir -p /mha/scripts
配置masterha_default.cnf文件
这是全局配置文件,缺省为/etc/masterha_default.cnf,适用于一个manager管理多套mysql replication的情况,在[server_default]下定义一些多套复制环境通用的global scope类型的参数。本例只有一套mysql replication,所以也可不用配置该文件,而是在对应的应用配置文件(appl.conf)下的[server_default]中定义相关参数。
执行mha相关命令时,会在/etc目录下搜索该配置文件,若找不到,虽然不会有什么错误,但会给出一个警告,如“[warning] global configuration file /etc/masterha_default.cnf not found.”。
为此可以在/etc目录下创建一个名为masterha_default.cnf的空文件,本例不打算这么做,而是在其中配置一些通用的[server_default]类参数,如下:
# vi /etc/masterha_default.cnf
[server default]
user = root
password = mysql --mysql密码
ssh_user = root
repl_user = repl
repl_password = repl_pwd
ping_interval = 3
ping_type = select
配置appl.conf文件
这是针对每一套mysql replication应用专门的配置文件,若管理多套mysql replication,可配置多个文件,其中包括[server_default]和[server_xxx]两个项目,分别用于配置app scope、local scope类型的参数。
# vi /etc/appl.cnf
[server default]
manager_workdir = /mha/appl
manager_log = /mha/appl/manager.log
remote_workdir = /mha/appl
#master_ip_failover_script=/mha/scripts/master_ip_failover
[server1]
hostname = 192.168.3.27
master_binlog_dir = /data/lib/mysql
candidate_master = 1
[server2]
hostname = 192.168.3.28
master_binlog_dir = /data/lib/mysql
candidate_master =1
[server3]
hostname = 192.168.3.25
no_master = 1
3.配置ssh等效连接因为mha管理节点以及各个node节点之间需要无密码登录并执行相关脚本,所以需要配置各个节点之间的ssh等效性,如下:
――生成密钥文件(各个节点均需执行)
# mkdir -p ~/.ssh
# cd .ssh
# /usr/bin/ssh-keygen -t rsa (提示处直接回车即可)
# /usr/bin/ssh-keygen -t dsa (提示处直接回车即可)
执行完成后,在/root/.ssh 目录下会生产四个密钥文件。
――任意一个节点执行即可(本例选择在manager节点执行)
# ssh 192.168.3.27 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.27 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.28 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.28 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.25 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.25 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.26 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.26 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# scp ~/.ssh/authorized_keys 192.168.3.27:.ssh/
# scp ~/.ssh/authorized_keys 192.168.3.28:.ssh/
# scp ~/.ssh/authorized_keys 192.168.3.25:.ssh/
――修改authorized_keys文件的权限为600(所有节点均需执行)
# chmod 600 ~/.ssh/authorized_keys
――测试一下
在各节点执行如下命令,测试一下,看是否不提示密码即可显示,否则则说明ssh配置不成功。
# ssh 192.168.3.26 hostname
# ssh 192.168.3.26 date
另外,还可采用mha提供的工具命令来检查,如下:
[root@mmm .ssh]# /usr/bin/masterha_check_ssh --conf=/etc/appl.cnf
fri jul 18 16:52:12 2014 - [info] reading default configuratoins from /etc/masterha_default.cnf..
fri jul 18 16:52:12 2014 - [info] reading application default configurations from /etc/appl.cnf..
fri jul 18 16:52:12 2014 - [info] reading server configurations from /etc/appl.cnf..
fri jul 18 16:52:12 2014 - [info] starting ssh connection tests..
fri jul 18 16:52:13 2014 - [debug]
fri jul 18 16:52:12 2014 - [debug] connecting via ssh from root@192.168.3.27(192.168.3.27:22) to root@192.168.3.28(192.168.3.28:22)..
fri jul 18 16:52:12 2014 - [debug] ok.
fri jul 18 16:52:12 2014 - [debug] connecting via ssh from root@192.168.3.27(192.168.3.27:22) to root@192.168.3.25(192.168.3.25:22)..
fri jul 18 16:52:12 2014 - [debug] ok.
fri jul 18 16:52:13 2014 - [debug]
fri jul 18 16:52:12 2014 - [debug] connecting via ssh from root@192.168.3.28(192.168.3.28:22) to root@192.168.3.27(192.168.3.27:22)..
fri jul 18 16:52:13 2014 - [debug] ok.
fri jul 18 16:52:13 2014 - [debug] connecting via ssh from root@192.168.3.28(192.168.3.28:22) to root@192.168.3.25(192.168.3.25:22)..
fri jul 18 16:52:13 2014 - [debug] ok.
fri jul 18 16:52:13 2014 - [debug]
fri jul 18 16:52:13 2014 - [debug] connecting via ssh from root@192.168.3.25(192.168.3.25:22) to root@192.168.3.27(192.168.3.27:22)..
fri jul 18 16:52:13 2014 - [debug] ok.
fri jul 18 16:52:13 2014 - [debug] connecting via ssh from root@192.168.3.25(192.168.3.25:22) to root@192.168.3.28(192.168.3.28:22)..
fri jul 18 16:52:13 2014 - [debug] ok.
fri jul 18 16:52:13 2014 - [info] all ssh connection tests passed successfully.
从中可以看到,该命令会从应用配置文件中读取相关信息(ip和ssh_user),然后在各个node之间相互验证,保证可以通过ssh方式相互登录(用于同步差异日志)。
4.配置hosts解析这一步的目的是在hostname和ip之间提供一个解析途径,配置方法很简单,就是将各个节点的主机名及对应的ip地址写入/etc/hosts文件,所有节点均需配置,且保持一致,如下:
# vi /etc/hosts
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
192.168.3.27 node1
192.168.3.28 node2
192.168.3.25 node3
192.168.3.26 mmm
为了省事,在一个节点配置,然后拷贝到其它节点即可;配置完成后,可以相互ping一下主机名,看能否成功解析。
5.搭建mysql主从复制按照规划,在node1、node2、node3上安装mysql数据库,并搭建成一主二从的mysql replication结构;具体操作不做说明了,可参考http://blog.csdn.net/dbaxiaosa/article/details/22421969 对于mha来说,搭建mysql replication需要注意以下几点:
read_only――是否限制slave实例为只读状态,缺省为0,即不限制,mha要求设置为1。
relay_log_purge――这个参数用于限制中继日志应用完之后是否删除,缺省为1,即应用完之后立即删除;在mha中,manager就是通过这些日志来同步各个slave之间的数据差异的,所以必须设置为0,即不删除中继日志。
log_bin――是否开启二进制日志,若某个slave可能被选择成为新的master,则必须开启;若某个slave被限制永远不会成为新的master,可以不用开启。
成功搭建后,通过mha命令检查一下,确保无误。
[root@mmm scripts]# /usr/bin/masterha_check_repl --conf=/etc/appl.cnf
mon jul 21 10:40:12 2014 - [info] reading default configuratoins from /etc/masterha_default.cnf..
mon jul 21 10:40:12 2014 - [info] reading application default configurations from /etc/appl.cnf..
mon jul 21 10:40:12 2014 - [info] reading server configurations from /etc/appl.cnf..
mon jul 21 10:40:12 2014 - [info] mha::mastermonitor version 0.55.
mon jul 21 10:40:12 2014 - [info] dead servers:
mon jul 21 10:40:12 2014 - [info] alive servers:
mon jul 21 10:40:12 2014 - [info] 192.168.3.27(192.168.3.27:3306)
mon jul 21 10:40:12 2014 - [info] 192.168.3.28(192.168.3.28:3306)
mon jul 21 10:40:12 2014 - [info] 192.168.3.25(192.168.3.25:3306)
mon jul 21 10:40:12 2014 - [info] alive slaves:
mon jul 21 10:40:12 2014 - [info] 192.168.3.28(192.168.3.28:3306) version=5.5.17-log (oldest major version between slaves) log-bin:enabled
mon jul 21 10:40:12 2014 - [info] replicating from 192.168.3.27(192.168.3.27:3306)
mon jul 21 10:40:12 2014 - [info] primary candidate for the new master (candidate_master is set)
mon jul 21 10:40:12 2014 - [info] 192.168.3.25(192.168.3.25:3306) version=5.5.17 (oldest major version between slaves) log-bin:disabled
mon jul 21 10:40:12 2014 - [info] replicating from 192.168.3.27(192.168.3.27:3306)
mon jul 21 10:40:12 2014 - [info] not candidate for the new master (no_master is set)
mon jul 21 10:40:12 2014 - [info] current alive master: 192.168.3.27(192.168.3.27:3306)
mon jul 21 10:40:12 2014 - [info] checking slave configurations..
mon jul 21 10:40:12 2014 - [warning] relay_log_purge=0 is not set on slave 192.168.3.28(192.168.3.28:3306).
mon jul 21 10:40:12 2014 - [warning] log-bin is not set on slave 192.168.3.25(192.168.3.25:3306). this host can not be a master.
mon jul 21 10:40:12 2014 - [info] checking replication filtering settings..
mon jul 21 10:40:12 2014 - [info] binlog_do_db= , binlog_ignore_db=
mon jul 21 10:40:12 2014 - [info] replication filtering check ok.
mon jul 21 10:40:12 2014 - [info] starting ssh connection tests..
mon jul 21 10:40:13 2014 - [info] all ssh connection tests passed successfully.
mon jul 21 10:40:13 2014 - [info] checking mha node version..
mon jul 21 10:40:14 2014 - [info] version check ok.
mon jul 21 10:40:14 2014 - [info] checking ssh publickey authentication settings on the current master..
mon jul 21 10:40:14 2014 - [info] healthcheck: ssh to 192.168.3.27 is reachable.
mon jul 21 10:40:14 2014 - [info] master mha node version is 0.54.
mon jul 21 10:40:14 2014 - [info] checking recovery script configurations on the current master..
mon jul 21 10:40:14 2014 - [info] executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/data/lib/mysql --output_file=/mha/appl/save_binary_logs_test --manager_version=0.55 --start_file=mysql-bin.000004
mon jul 21 10:40:14 2014 - [info] connecting to root@192.168.3.27(192.168.3.27)..
creating /mha/appl if not exists.. ok.
checking output directory is accessible or not..
ok.
binlog found at /data/lib/mysql, up to mysql-bin.000004
mon jul 21 10:40:14 2014 - [info] master setting check done.
mon jul 21 10:40:14 2014 - [info] checking ssh publickey authentication and checking recovery script configurations on all alive slave servers..
mon jul 21 10:40:14 2014 - [info] executing command : apply_diff_relay_logs --command=test --slave_user='root' --slave_host=192.168.3.28 --slave_ip=192.168.3.28 --slave_port=3306 --workdir=/mha/appl --target_version=5.5.17-log --manager_version=0.55 --relay_log_info=/data/lib/mysql/relay-log.info --relay_dir=/data/lib/mysql/ --slave_pass=xxx
mon jul 21 10:40:14 2014 - [info] connecting to root@192.168.3.28(192.168.3.28:22)..
checking slave recovery environment settings..
opening /data/lib/mysql/relay-log.info ... ok.
relay log found at /data/lib/mysql, up to mysql-relay-bin.000006
temporary relay log file is /data/lib/mysql/mysql-relay-bin.000006
testing mysql connection and privileges.. done.
testing mysqlbinlog output.. done.
cleaning up test file(s).. done.
mon jul 21 10:40:14 2014 - [info] executing command : apply_diff_relay_logs --command=test --slave_user='root' --slave_host=192.168.3.25 --slave_ip=192.168.3.25 --slave_port=3306 --workdir=/mha/appl --target_version=5.5.17 --manager_version=0.55 --relay_log_info=/data/lib/mysql/relay-log.info --relay_dir=/data/lib/mysql/ --slave_pass=xxx
mon jul 21 10:40:14 2014 - [info] connecting to root@192.168.3.25(192.168.3.25:22)..
creating directory /mha/appl.. done.
checking slave recovery environment settings..
opening /data/lib/mysql/relay-log.info ... ok.
relay log found at /data/lib/mysql, up to mysql-relay-bin.000008
temporary relay log file is /data/lib/mysql/mysql-relay-bin.000008
testing mysql connection and privileges.. done.
testing mysqlbinlog output.. done.
cleaning up test file(s).. done.
mon jul 21 10:40:15 2014 - [info] slaves settings check done.
mon jul 21 10:40:15 2014 - [info]
192.168.3.27 (current master)
+--192.168.3.28
+--192.168.3.25
mon jul 21 10:40:15 2014 - [info] checking replication health on 192.168.3.28..
mon jul 21 10:40:15 2014 - [info] ok.
mon jul 21 10:40:15 2014 - [info] checking replication health on 192.168.3.25..
mon jul 21 10:40:15 2014 - [info] ok.
mon jul 21 10:40:15 2014 - [warning] master_ip_failover_script is not defined.
mon jul 21 10:40:15 2014 - [warning] shutdown_script is not defined.
mon jul 21 10:40:15 2014 - [info] got exit code 0 (not master dead).
mysql replication health is ok.
注:如果有错误,根据检查的错误提示,进行相应的修改设置()。
从中可以看出,该命令首先从主配置文件和应用配置文件中读取相关参数,然后检查各个slave的状态、参数配置、ssh连通性、执行save_binary_logs、apply_diff_relay_logs命令等操作,确保最后的提示为“mysql replication health is ok”,否则需要重新检查mysql replication配置。
另外,其中给出了两个警告,提示没有定义master_ip_failover_script、shutdown_script,这个暂且不管,在后面环节再详细说明。
三、测试经过上面一系列步骤,成功搭建及配置了mha,下面我们就来简单试用一下,并进行一下功能测试。
1.命令工具mha提供的命令工具包括manager工具和node工具,简单介绍如下:
manager工具
/usr/bin/masterha_check_repl ――检查mysql replication是否正常;
/usr/bin/masterha_conf_host ――添加或删除配置的server信息;
/usr/bin/masterha_master_switch ――用于手动master切换;
/usr/bin/masterha_check_ssh ――检查各个node之间ssh登录是否正常;
/usr/bin/masterha_manager ――开启mha
/usr/bin/masterha_secondary_check ――检查多路由配置;
/usr/bin/masterha_check_status ――检查mha是否开启并正常运行;
/usr/bin/masterha_master_monitor ――手动开启监控,启动mha时会自动启动监控
/usr/bin/masterha_stop ――关闭mha
node工具
/usr/bin/save_binary_logs ――保存和复制master的二进制日志;
/usr/bin/apply_diff_relay_logs ――识别差异的中继日志事件并应用于其它slave;
/usr/bin/filter_mysqlbinlog ――去除不必要的rollback事件(mha已不再使用该工具);
/usr/bin/purge_relay_logs ――清除中继日志(不会阻塞sql线程);
备注:node端工具通常由mha manager的脚本触发调用,无需dba操作。
2.开启mha在开启mha之前,可以先通过masterha_check_repl检查一下mysql replication是否正常,通过masterha_check_ssh检查一下各个node之间ssh登录是否正常,这在前面均已试用该命令。
开启mha的命令为masterha_manager,其用法如下:
[root@mmm scripts]# /usr/bin/masterha_manager --help
usage:
masterha_manager --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_manager) for
details.
可见其只有两个参数,--global_conf缺省为/etc/masterha_default.cnf,本例中符合缺省要求,所以可以不指定,为了方便,通过如下命令使其后台运行。如下:
[root@mmm appl]# /usr/bin/masterha_manager --conf=/etc/appl.cnf &
[1] 5674
[root@mmm appl]# mon jul 21 10:56:32 2014 - [info] reading default configuratoins from /etc/masterha_default.cnf..
mon jul 21 10:56:32 2014 - [info] reading application default configurations from /etc/appl.cnf..
mon jul 21 10:56:32 2014 - [info] reading server configurations from /etc/appl.cnf..
为了使mha持续运行在服务器端,可通过如下命令使其不挂起运行在后台:
[root@mmm appl]# nohup /usr/bin/masterha_manager --conf=/etc/appl.cnf &
[1] 5905
[root@mmm appl]# nohup: appending output to `nohup.out'
mha开启之后,会在其工作目录下生成如下两个文件:
[root@mmm appl]# ls
appl.master_status.health manager.log
其中appl.master_status.health为master实例的健康监控文件,mha开启时生成,关闭后消失,里面内容如下:
[root@mmm appl]# more appl.master_status.health
5674 0:ping_ok master:192.168.3.27
而manager.log为mha的日志文件,其内容较多,执行masterha_check_repl命令时的输入内容类似。
可通过masterha_check_status命令检查mha是否在运行,比如:
[root@mmm appl]# /usr/bin/masterha_check_status --conf=/etc/appl.cnf
appl (pid:5905) is running(0:ping_ok), master:192.168.3.27
若mha正常运行,则提示如上,否则提示:appl is stopped(2:not_running).
对于一个正在运行的mha,可通过masterha_stop命令关闭,如下:
[root@mmm appl]# /usr/bin/masterha_check_status --conf=/etc/appl.cnf
appl is stopped(2:not_running).
3.master自动故障转移及差异日志恢复》模拟复制不同步,造成数据差异
――关闭node3的复制线程,然后在master主库(node1)上创建一张表,以此造成node3数据不同步
mysql> stop slave;
query ok, 0 rows affected (0.01 sec)
mysql> use test;
database changed
mysql> create table student(s_id int,s_name varchar(10),primary key(s_id));
query ok, 0 rows affected (0.01 sec)
――关闭node2的复制进线程,
mysql> stop slave;
query ok, 0 rows affected (0.01 sec)
mysql> insert into student(s_id,s_name) values(1,'aaa');
query ok, 1 row affected (0.01 sec)
通过这个模拟,现在node1(master)上有一张student表,并有一条数据;node2(slave1)上有student这张表,但里面没有数据;node3(slave2)上还没有student这张表,所以这套复制环境的3个节点目前是不同步的。
》关闭node1(master)的mysqld进程,模拟mysql实例故障
[root@node1 data]# service mysql stop;
shutting down mysql... [ ok ]
此时检查node2,发现已恢复了差异数据(一条记录),停掉了原来的复制线程,被选择为新的master,并赋予写操作权限。
mysql> select * from student;
+------+--------+
| s_id | s_name |
+------+--------+
| 1 | aaa |
+------+--------+
1 row in set (0.00 sec)
mysql> show slave status \g;
empty set (0.00 sec)
mysql> show variables like 'read_only%';
+---------------+-------+
| variable_name | value |
+---------------+-------+
| read_only | off |
+---------------+-------+
1 row in set (0.00 sec)
检查node3,发现差异数据也被恢复(student表和一条记录),并将master_host指向新的master(node2)
mysql> use test;
database changed
mysql> select * from student;
+------+--------+
| s_id | s_name |
+------+--------+
| 1 | aaa |
+------+--------+
1 row in set (0.00 sec)
mysql> show slave status \g;
*************************** 1. row ***************************
slave_io_state: waiting for master to send event
master_host: 192.168.3.28 (这里指向了新的master:node2)
master_user: repl
master_port: 3306
connect_retry: 60
master_log_file: mysql-bin.000005
read_master_log_pos: 520069
relay_log_file: mysql-relay-bin.000002
relay_log_pos: 253
relay_master_log_file: mysql-bin.000005
slave_io_running: yes
slave_sql_running: yes
replicate_do_db:
replicate_ignore_db:
replicate_do_table:
replicate_ignore_table:
replicate_wild_do_table:
replicate_wild_ignore_table:
last_errno: 0
last_error:
skip_counter: 0
exec_master_log_pos: 520069
relay_log_space: 409
until_condition: none
until_log_file:
until_log_pos: 0
master_ssl_allowed: no
master_ssl_ca_file:
master_ssl_ca_path:
master_ssl_cert:
master_ssl_cipher:
master_ssl_key:
seconds_behind_master: 0
master_ssl_verify_server_cert: no
last_io_errno: 0
last_io_error:
last_sql_errno: 0
last_sql_error:
replicate_ignore_server_ids:
master_server_id: 28
1 row in set (0.00 sec)
从中可以看到,当mha监控到master实例故障时,自动恢复了master与slave以及slaves之间的差异日志,然后从两个slave实例中选择node2充当新的master,并将另一个slave实例node2重新指向到新的master实例node2开始复制,组成新的mysql replication结构。而原来的master则被排除在新的mysql replication结构之外,即使其恢复正常,也不会被自动加入。
4.手动master故障切换开启mha后,自动启动监控功能,当监测到master故障时,自动实现切换。
另外,在没有开启mha的情况下,我们还可以执行交互式的手动切换、非交互式的自动切换,及在线切换master到不同主机等操作,这些都是通过masterha_master_switch命令工具实现的。
该命令用法如下:
[root@mmm appl]# /usr/bin/masterha_master_switch --help
usage:
# for master failover
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
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.
从中可以看到,该命令有# for master failover、# for online master switch两个用法,区别在于前者需要指定master的状态为dead,后者需要指定master的状态为alive。
下面通过两个示例来体会一下:
》 for master failover
现在的master为node2,手动停止mysqld实例
[root@node2 ~]# service mysql stop
shutting down mysql... [ ok ]
下面手动执行master故障切换,这个切换过程是交互式的,期间需要输入指令来确认;另外,由于mha没有启动,也就不会自动监控master实例状态,所以需要指定master_state为dead,并且指定dead master的host、ip、port等信息,如下:
[root@mmm ~]# /usr/bin/masterha_master_switch --master_state=dead --conf=/etc/appl.cnf --dead_master_host=node2
》 for online master switch
这个功能是指master实例运行正常,但出于运维工作(比如:更换硬件等),需要将其上的master切换到另一主机上。
切换过程都一样,期间也需要交互,只不过指定master_state=alive即可,如下:
# /usr/bin/masterha_master_switch --master_state=alive --conf=/etc/appl.cnf
通过这两个示例,我们知道,不管是自动master故障切换,还是手动交互式master切换,以及在线切换master到另外主机,其切换过程和步骤都是一样的。
至此mha成功搭建完毕,该小节告一段落,通过前面的学习,我们了解了mha这一高可用工具的master故障切换功能及实现原理,但若在实际生产环境中采用它,还存在许多问题,需要进一步的改进与配置。我们先来探讨一下上面这套环境中存在的问题,及mha提供的解决办法。
问题: 前端应用连接问题
理论上来说,后端数据库故障切换,对前端应用应该是透明的;也就是说:当master从一台主机切换到另一台主机上时,前端应用不需要做任何额外的操作,主要体现为数据库连接串变化。
对于这个问题,通常有两种解决方案:一是引入vip,当数据库切换时,vip随之切换;常用的ha软件中,大多是采用vip实现的,比如oracle rac,sql server群集、heartbeat等。二是采用全局目录数据库,即将应用和数据库之间的连接映射为一个列表,当数据库切换时,更改这个映射列表。mha并不限制用户使用那种方式,只是通过master_ip_failover_script配置参数提供了一个接口。 若采用vip的方式来实现,可引入第三方软件,比如keplived等,也可自行编写一个vip切换脚本。
由于篇幅问题,以上两种方案解决方案,等有时间再继续写入到 mysql高可用系列之mha(二)