MHA高可用

一 MHA布景介绍

MHA 是Perl言语写的,开源的MYSQL毛病切换计划;全称:Master High Availability,毛病切换时刻10-30s

有人说,我不要MHA行不行啊; 能够,没问题, 假如主数据库毛病了?

首先,你需求手动一个一个地登录上一切的SLAVE从库,然后一个个比照,看谁履行的BINLOG比较新,然后将其作为主库。

接下来,你还需求手动把一切的从库CHANGE MASTER到新选出的主库。

一个字“费力”!

这要是别的事,也还能够忍,但主库挂掉,会导致业务无法访问,一堆人站你旁边看着你,到时分一紧张再忘记开写了、SLAVE挂不上去,这个影响时刻就不是一星半点了;

为了处理上述问题,就有人写了个程序,来履行主动的主从毛病切换,这便是MHA;

二 MHA简介

  MHA(Master High Availability)是由日本人 yoshinorim(原就职于DeNA现就职于FaceBook)开发的一款成熟的、开源的 MySQL 的高可用程序。它为 MySQL 主从仿制架构供给了主动毛病切换( automating master failover) 功用。 MHA 在监控到 master 节点毛病时,会提高其中拥有最新数据的 slave 节点成为新的master 节点,在此期间,MHA 会经过于其它从节点获取额外信息来避免共同性方面的问题,从而在最大程度上确保数据的共同性,以到达真正含义上的高可用,而且整个毛病搬运进程对运用程序完全透明。最值得称赞的一点是:这一主动毛病切换操作,MHA能在10~30秒之内完结

​ 此外,MHA 还供给了 master 节点的在线切换功用,即按需切换 master/slave 节点,大概0.5-2秒内即可完结。

​ 现在MHA首要支撑一主多从的架构,要建立MHA,要求一个仿制集群中有必要最少有三台数据库服务器,例如一主二从。由于至少需求三台服务器,出于机器本钱的考虑,淘宝也在该基础上进行了改造,现在淘宝的TMHA现已支撑一主一从。

三 MHA作业原理

3.1 MHA的组成

MHA由node和manager组成;

  • MHA Node(数据节点):
相当于监控客户端,一切数据库机器都需求布置node
  • MHA Manager(办理节点)

    Manager相当于服务端,MHA Manager会守时勘探集群中的master节点,当master出现毛病时,它能够主动将最新数据的slave提高为新的master,然后将一切其他的slave从头指向新的master(假如原主库康复,只能当从库)。

    一般单独布置在一台独立机器上办理多个 master/slave 集群(组),每个 master/slave 集群称作一个 application,用来办理统筹整个集群。

    Manager应该尽量避免布置在主库上,不然主机一挂则全挂,不仅主库完蛋了,担任主动搬迁的Manager也完蛋了,也没人担任主动毛病搬迁了,导致架构不可用了。

    能够考虑布置在某一个slave上,此刻这台主机挂掉了,仅仅挂了一个slave,以及Manager,假如此刻你不是倒了霉,(主库也挂了),那还不至于架构不可用。但有一点需求留意的是:假如Manager布置在slave上,那么该slave就无法被晋级为主库;

 由上图咱们能够看出,每个仿制组内部和 Manager 之间都需求ssh完结无暗码互连,只要这样,在 Master 出毛病时, Manager 才能顺利的衔接进去,完结主从切换功用。

3.2 MHA主动毛病切换的过程

(1), Manager会每隔3秒钟勘探一次MASTER主库; (Hi, 主库你还活着吗?)

ping_interval 操控间隔时刻;
ping_type 操控勘探方法,SELECT(履行SELECT 1)和CONNECT(创立衔接/断开衔接)

(2), 假如Manager勘探到MASTER主库毛病、无法访问,Manager会履行下面操作:

1、从其他node发起ssh衔接,检查主库是否能够SSH上去;
2、从其他node发起mysql衔接,检查MASTER库是否能够登陆;

(3), 假如一切Node节点ssh衔接、msyql主库衔接均衔接失利,则开端毛病搬运,

简单地说

1.找到数据最新的从库(经过比照relay-log,检查show slave status即可)
2.将最新的从库上的新数据同步到其他从库
3.提高一个从库为主库(一般状况提高数据最新的,二般状况提高咱们指定的从库为主库)
4.经过本来主库的binlog补全新的主库数据
5.其他从库以新的主库为主做主从仿制

具体过程如下:

Phase 1 Configuration Check Phase.. 检查数据库版别
检查是否启用
GTID
检查从库是否存活
检查装备文件的
candidate
Phase 2 Dead Master Shutdown Phase. 该阶段会调用master_ip_failover脚本;去封闭一切NodeIO Thread
调用shutdown_script 强制封闭MASTER实例,避免运用程序来衔接;
Phase 3 Master Recovery Phase..  
Phase 3.1 Getting Latest Slaves Phase. 检查一切节点,从show slave status中比照获取最新的binlog/position
Phase 3.2 Saving Dead Master’s Binlog Phase.. 假如老的Master能够SSH,上去获取BINLOG,从positionEND方位,获取这段BINLOGMASETER产生这段BINLOG,还未来得及发送给SLAVE)将这部分日志发送给Manager节点(manager_workdir方位)
假如毛病
Master无法SSH,则无法获取这段日志
Phase 3.3 Determining New Master Phase.. 比照一切SLAVE,从最新SALVE中同步差异realy log给其他slave;最终确保一切SLAVE数据共同
Phase 3.3 New Master Diff Log Generation Phase.. 确认新master 是否为最新slave,假如不是,则从最新slave获取差异日志;
manager上获取的BINLOG日志发送给new master
Phase 3.4 Master Log Apply Phase.. 比照新masterExec_Master_Log_PosRead_Master_Log_Pos,判断康复的方位;
在本地回放
3.3 Phase的差异日志;
获取新
masterbinlogposition
Phase 4 Slaves Recovery Phase..  
Phase 4.1 Starting Parallel Slave Diff Log Generation Phase. 对每个SLAVE康复:一切SLAVE和最新Slave做比照,假如position不共同,则出产差异日志
Phase 4.2 Starting Parallel Slave Log Apply Phase. 每个SLAVE 运用差异日志;
履行
CHANGE MASTER 挂在到新Master
Phase 5 New master cleanup phase.. reset slave all;

四 MHA的优点总结

1、主动的毛病检测与搬运,一般在10-30秒以内;

2、MHA还供给在线主库切换的功用,能够安全地切换当时运转的主库到一个新的主库中(经过将从库提高为主库),大概0.5-2秒内即可完结。

3、很好地处理了主库溃散数据的共同性问题

4、不需求对当时的mysql环境做重大修正

5、不需求在现有的仿制结构中增加额外的服务器,仅需求一个manager节点,而一个Manager能办理多套仿制,所以能大大地节约服务器的数量;

6、功用优异,能够作业在半同步和异步仿制结构,支撑gtid,当监控mysql状况时,仅需求每隔N秒向master发送ping包(默许3秒),所以对功用无影响。你能够理解为MHA的功用和简单的主从仿制结构功用相同。

7、只要replication支撑的存储引擎都支撑MHA,不会局限于innodb

8、关于一般的keepalived高可用,当vip在一台机器上的时分,另一台机器是搁置的,而MHA中并无搁置主机。

五 GTID主从仿制

5.1 什么是GTID

​ 在MHA主动毛病切换进程中,MHA企图从宕机的主服务器上保存二进制日志,最大程度的确保数据的不丢掉,但这并不总是可行的。例如,假如主服务器硬件毛病或无法经过ssh访问,MHA无法保存二进制日志,只进行毛病搬运而丢掉了最新的数据。运用自MySQL 5.5开端引入的半同步仿制,能够大大降低数据丢掉的风险。

  MHA能够与半同步仿制结合起来。假如只要一个slave现已收到了最新的二进制日志,MHA能够将最新的二进制日志运用于其他一切的slave服务器上,因此能够确保一切节点的数据共同性,或许采用GTID。

​ 那什么是GTID呢???

从MySQL 5.6.2 开端新增了一种根据 GTID 的仿制方法,用以替代曾经传统的仿制方法,到MySQL5.6.10后逐渐完善。经过 GTID 确保了每个在主库上提交的业务在集群中有一个仅有的ID。这种方法强化了数据库的主备共同性,毛病康复以及容错才能,那么它怎么做到的呢?
要想在散布式集群环境中不丢掉业务,就有必要为每个业务定制一个大局仅有的ID号,而且该ID是趋势递加的,以此咱们便能够便利地顺序读取、不丢业务,其实GTID便是一种很好的散布式ID实践计划,它满足散布ID的两个基本要求
1)大局仅有性
2)趋势递加
GTID (Global Transaction ID大局业务ID)是怎么做到大局仅有且趋势递加的呢,它是由UUID+TID两部分组成
	UUID是数据库实例的标识符
	TID表示业务提交的数量,会跟着业务的提交递加
	#具体形式:5426a3c1-ade1-11e9-90b3-000c29bb4490:23
因此他与主库上提交的每个业务相关联,GTID不仅对其发起的服务器是仅有的,而且在给定仿制设置中的一切服务器都是仅有的,即一切的业务和一切的GTID都是1对1的映射。
当在主库上提交业务或许被从库运用时,能够定位和追寻每一个业务,对DBA来说含义就很大了,咱们能够恰当的解放出来,不必手艺去能够找偏移量的值了,而是经过CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=1的即可便利的建立从库,在毛病修正中也能够采用MASTER_AUTO_POSITION=‘X’的方法。
5.7版别GTID做了增强,不手艺敞开也主动维护匿名的GTID信息

5.2 GTID主从的原理

(1)一个GTID的生命周期

1.业务在主库上履行并提交给业务分配一个gtid(由主库的uuid和该服务器上未运用的最小业务序列号),该GTID被写入到binlog中。
2.备库读取relaylog中的gtid,并设置session等级的gtid_next的值,以告知备库下一个业务有必要运用这个值
3.备库检查该gtid是否现已被其运用并记载到他自己的binlog中。slave需求担保之前的业务没有运用这个gtid,也要担保此刻已分读取gtid,但未提交的业务也不恩呢过运用这个gtid.
4.由于gtid_next非空,slave不会去生成一个新的gtid,而是运用从主库取得的gtid。这能够确保在一个仿制拓扑中的同一个业务gtid不变。由于GTID在大局的仅有性,经过GTID,咱们能够在主动切换时对一些杂乱的仿制拓扑很便利的提高新主库及新备库,例如经过指向特定的GTID来确定新备库仿制坐标。

(2)架构图

相同的GTID不能被履行两次,假如有相同的GTID,会主动被skip掉。

slave1:将自己的UUID1:1发送给master,然后接纳到了UUID1:2,UUID1:3 event

slave2:将自己的UUID1:1,UUID1:2发送给master,然后接纳到了UUID1:3事情

5.3 布置根据GTID的主从仿制

留意:

​ ? 主库和从库都要敞开binlog

  ? 主库和从库server-id有必要不同

  ? 要有主从仿制用户

主:mysql5.6,192.168.15.100,装备如下

[mysqld]
。。。。。。。
server-id=100
binlog_format=row
log-bin=mysql-bin
skip-name-resolve # 越过域名解析(非有必要)
gtid-mode=on # 启用gtid类型,不然便是一般的仿制架构
enforce-gtid-consistency=true #强制GTID的共同性
log-slave-updates=1 # slave更新是否记入日志(5.6有必要的)
relay_log_purge = 0 # 封闭relay_log主动铲除功用,保证毛病时的数据共同

从1:mysql5.6,192.168.15.101,装备如下,只要server-id与主不同

[mysqld]
。。。。。。。
server-id=101
binlog_format=row
log-bin=mysql-bin
skip-name-resolve # 越过域名解析(非有必要)
gtid-mode=on # 启用gtid类型,不然便是一般的仿制架构
enforce-gtid-consistency=true #强制GTID的共同性
log-slave-updates=1 # slave更新是否记入日志(5.6有必要的)
relay_log_purge = 0 # 封闭relay_log主动铲除功用,保证毛病时的数据共同

从2:mysql5.6,192.168.15.102,装备如下,只要server-id与主不同

[mysqld]
。。。。。。。
server-id=102
binlog_format=row
log-bin=mysql-bin
skip-name-resolve # 越过域名解析(非有必要)
gtid-mode=on # 启用gtid类型,不然便是一般的仿制架构
enforce-gtid-consistency=true #强制GTID的共同性
log-slave-updates=1 # slave更新是否记入日志(5.6有必要的)
relay_log_purge = 0 # 封闭relay_log主动铲除功用,保证毛病时的数据共同

主库创立仿制账户

mysql> GRANT REPLICATION SLAVE ON *.* TO jason@'%' IDENTIFIED BY '123';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

两个从库敞开仿制

change master to
    master_host='192.168.15.100',
    master_user='jason',
    master_password='123',
    MASTER_AUTO_POSITION=1;

发动从库的仿制

start slave;
show slave status\G
show variables like '%gtid%';

测验主从

假如想制造双主,过程如下

# 找一台从库,假定为192.168.15.101,在该主机上创立账号
GRANT REPLICATION SLAVE ON *.* TO jason@'%' IDENTIFIED BY '123';
flush privileges;
# 在主库上履行下述操作,指向从库192.168.15.101
change master to 
    master_host='192.168.15.101',
    master_user='jason',
    master_password='123',
    MASTER_AUTO_POSITION=1;
# 敞开主库的slave
start slave;

5.4 越过业务

传统的仿制例,假如主从仿制遇到了某条sql错误,SQL停了,咱们能够经过下述操作越过错误
	stop slave;
	set global sql_slave_skip_counter=1;
	start slave;
在传统的主从里,counter=1是越过一条sql,而GTID是根据业务的主从仿制,假如越过便是越过一整个业务,所以上述方法并不适用于GTID
#越过业务的方法:
1)中止slave进程
mysql> STOP SLAVE;
2)设置业务号,履行show slave status\G检查Retrieved_Gtid_Set的值即业务号
在session里设置gtid_next,即越过这个GTID
mysql> SET GTID_NEXT= '6d257f5b-5e6b-11e8-b668-5254003de1b6:1'
3)设置空事物
mysql> BEGIN; COMMIT;
4)康复事物号
mysql> SET SESSION GTID_NEXT = AUTOMATIC;
5)发动slave进程
mysql> START SLAVE;

5.5 GTID优缺点总结

GTID相比传统仿制的优点(新特性):

1、一个业务对应一个仅有ID,一个GTID在一个服务器上只会履行一次,强化了共同性

2、GTID是用来替代传统仿制的方法,GTID仿制与一般仿制形式的最大不同便是不需求指定二进制文件名和方位,直接主动查找

3、GTID会敞开多个SQL线程,每一个库,敞开一个SQL线程

4、支撑延时仿制

GTID的约束:

1.不支撑非业务引擎

2.不支撑create table t1(…) select * from t2; 句子仿制(主库直接报错)

  原理:( 会生成两个sql,一个是DDL创立表SQL,一个是insert into 插入数据的sql。

  由于DDL会导致主动提交,所以这个sql至少需求两个GTID,但是GTID形式下,只能给这个sql生成一个GTID )  

3.不答应一个SQL同时更新一个业务引擎表和非业务引擎表

4.在一个仿制组中,有必要要求共同敞开GTID或许是封闭GTID

5.敞开GTID需求重启(5.7除外)

6.敞开GTID后,就不再运用本来的传统仿制方法

7.关于create temporary table 和 drop temporary table句子不支撑

8.不支撑sql_slave_skip_counter

9.mysqldump 备份起来很费事,需求额外加参数 –set-gtid=on

六 布置MHA

6.1 环境预备

机器名称 IP地址 角色 补白
manager 192.168.15.200 Manager操控器 用于监控办理
master 192.168.15.100 主数据库服务器 敞开binlog、relay-log,封闭relay_log_purge
slave1 192.168.15.101 从1数据库服务器 敞开binlog、relay-log,封闭relay_log_purge、设置read_only=1
slave2 192.168.15.102 从2数据库服务器 敞开binlog、relay-log,封闭relay_log_purge、设置read_only=1

先根据上一小节完结根据GTID的一主两从仿制,在做主从之前,要确保主从数据的共同性。

然后需求知道的是:

  • 1、一切数据库服务器都需求敞开binlog日志

  • 2、一切数据库都需求有主从仿制用户,但咱们之前在主库上履行过下述指令,从库现已同步过去了,所以不必重复创立,重复创立了也没啥卵用

    GRANT REPLICATION SLAVE ON *.* TO jason@'%' IDENTIFIED BY '123';
    flush privileges;
    
  • 3、需求在主库上创立一个办理用户,用于日后MHA的办理

    # 在主库上履行即可,从库会同步过去
    grant all on *.* to 'mhaadmin'@'%' identified by '666';
    flush privileges;
    
  • 4、MHA 对 MYSQL 仿制环境有特殊要求,例如各节点都要敞开二进制日志及中继日志,各个“slave节点”有必要显式启用3其read-only属性,并封闭relay_log_purge功用等。所以咱们需求

    #1、在从库上进行操作
    	#设置只读,不要增加装备文件,由于从库以后或许变成主库
    	mysql> set global read_only=1;
    #2、在一切库上都进行操作(这一步咱们在5.3小节现已做过了,此处疏忽即可)
    	#封闭MySQL主动铲除relaylog的功用
    	mysql> set global relay_log_purge = 0;
    	#编辑装备文件
    	[root@mysql-db02 ~]# vim /etc/my.cnf
    	[mysqld]
    	#禁用主动删去relay log永久生效
    	relay_log_purge = 0
    

6.2 装备免密登录(一切主机之间互做)

装备免密登录(每一台机器都履行下述指令)

#创立秘钥对
#正常创立 ssh-keygen 需求交互 按回车,用以下方法越过交互
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
#发送公钥,包括自己
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.15.200
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.15.100
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.15.101
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.15.102

6.3 装置软件包

装置依赖(一切机器)

# 装置yum源
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
# 装置MHA依赖的perl包
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager

留意先后顺序

先在一切主机上装置node包

wget https://qiniu.wsfnk.com/mha4mysql-node-0.58-0.el7.centos.noarch.rpm --no-check-certificate
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

然后再去manager主机装置manager包(manager机器,192.168.15.200)

wget https://qiniu.wsfnk.com/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm --no-check-certificate
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

6.4 装备MHA Manager

(1)在Manager主机上创立作业目录

mkdir -p /service/mha/
mkdir /service/mha/app1

(2) 修正装备

[rml_read_more]:
vim /service/mha/app1.cnf #为什么叫app1呢,由于他能够办理很多套集群,后边的能够叫app2

[server default]
#日志寄存途径
manager_log=/service/mha/manager.log
#界说作业目录方位
manager_workdir=/service/mha/app1
#binlog寄存目录(假如三台数据库机器布置的途径不相同,能够将装备写到相应的server下面)
#master_binlog_dir=/usr/local/mysql/data
#设置ssh的登录用户名
ssh_user=root
#假如端口修正不是22的话,需求加参数,不建议改ssh端口
#不然后续如担任VIP漂移的perl脚本也都得改,很费事
ssh_port=22
#办理用户
user=mhaadmin
password=666
#仿制用户
repl_user=jason  
repl_password=123
#检测主库心跳的间隔时刻
ping_interval=1
[server1]
# 指定自己的binlog日志寄存目录
master_binlog_dir=/var/lib/mysql
hostname=192.168.15.100
port=3306
[server2]
#暂时注释掉,先不运用
#candidate_master=1
#check_repl_delay=0
master_binlog_dir=/var/lib/mysql
hostname=192.168.15.101
port=3306
[server3]
master_binlog_dir=/var/lib/mysql
hostname=192.168.15.102
port=3306
# 1、设置了以下两个参数,则该从库成为候选主库,优先级最高
# 不管怎样都切到优先级高的主机,一般在主机功用差异的时分用         
candidate_master=1
# 不管优先级高的备选库,数据延时多久都要往那切
check_repl_delay=0
# 2、上述两个参数详解如下:
# 设置参数candidate_master=1后,则判断该主机为为候选master,产生主从切换以后将会将此从库提高为主库,即使这个主库不是集群中事情最新的slave。
# 默许状况下假如一个slave落后master 100M的relay logs的话,MHA将不会挑选该slave作为一个新的master,由于关于这个slave的康复需求花费很长时刻,经过设置check_repl_delay=0,MHA触发切换在挑选一个新的master的时分将会疏忽仿制延时,这个参数关于设置了candidate_master=1的主机非常有用,由于这个候选主在切换的进程中一定是新的master
# 3、应该为什么节点设置这俩参数,从而把该节点的优先级调高
# (1)、多地多中心,设置本地节点为高权重
# (2)、在有半同步仿制的环境中,设置半同步仿制节点为高权重
# (3)、你觉着哪个机器合适做主节点,装备较高的 、功用较好的

6.5 检测mha装备状况

#测验免密衔接
1.运用mha指令检测ssh免密登录
masterha_check_ssh --conf=/service/mha/app1.cnf
	ALL SSH ... successfilly 表示ok了
2.运用mha指令检测主从状况
masterha_check_repl --conf=/service/mha/app1.cnf
	... Health is OK
#假如出现问题,或许是反向解析问题,装备文件加上
    skip-name-resolve
#还有或许是主从状况,mha用户暗码的状况

6.6 发动MHA

nohup masterha_manager --conf=/service/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /service/mha/manager.log 2>&1 &
指令参数:
--remove_dead_master_conf       该参数代表当产生主从切换后,宕机库的装备信息将会从装备文件中移除。
--manger_log                    日志寄存方位
--ignore_last_failover          在缺省状况下,假如MHA检测到接连产生宕机,且两次宕机间隔缺乏8小时的话,则不会进行Failover,之所以这样约束是为了避免ping-pong效应。该参数代表疏忽前次MHA触发切换产生的文件,默许状况下,MHA产生切换后会在日志目录,也便是上面设置的manager_workdir目录中产生app1.failover.complete文件,下次再次切换的时分假如发现该目录下存在该文件将不答应触发切换,除非在第一次切换后收到删去该文件,为了便利,这儿设置为--ignore_last_failover。
#MHA的安全机制:
	1.完结一次切换后,会生成一个锁文件在作业目录中
	2.下次切换之前,会检测锁文件是否存在
	3.假如锁文件存在,8个小时之内不答应第二次切换

6.6 测验主动切换与康复

演练包括主动切换和手动切换两部分。

当主库宕机时,会产生主动切换,咱们先来模拟以下被迫切换与康复

模拟被迫切换一定要中止数据,不要重启数据库

#检查日志
tail -f /service/mha/manager.log
#停掉主库master
[root@db01 ~]# systemctl stop mysql
	提高数据量最多的为主库
	假如数据量相同,根据装备文件里边server的顺序切换
#假如把原主库修正,再把提高的主库中止,谁会是主库?
	数据量相同的状况下,根据server标签来切换的,标签越小优先级越高
#分析日志内容
#日志最终有一个sendreport机制,能够发送邮件给咱们运维,不过一般不必,咱们有zabbix能够帮咱们监控
#最终履行的时分删去了主库的server信息,他会给他加上注释,然后删去注释的内容

6.7 修正MHA毛病的主库

MHA环境修正过程:
#1.发动宕机的主库
systemctl start mysql
#2.将宕机的库作为从库指向新主库,此刻为'192.168.15.102',能够经过检查日志文件确认新主库地址: grep -i 'change master to' /service/mha/manager.log 
stop slave;
CHANGE MASTER TO MASTER_HOST='192.168.15.102', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='jason', MASTER_PASSWORD='123';
start slave;
3.假如发动manager时加入了参数--remove_dead_master_conf ,则此处需求将修正后的数据库信息装备到文件中
vim /service/mha/app1.cnf
[server1]
# 指定自己的binlog日志寄存目录
master_binlog_dir=/var/lib/mysql
hostname=192.168.15.100
port=3306
5.再次发动MHA(毛病搬迁一次masterha_manager就完毕了,所以毛病库修正后需求从头发动)
nohup masterha_manager --conf=/service/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /service/mha/manager.log 2>&1 &
6.检测MHA发动状况
masterha_check_status --conf=/service/mha/app1.cnf

这个是为了避免MHA切换以后进程退出,官网引荐运用daemon的方法运转,

6.7 主库切换优先级

(1)根据数据量是否最新进行主动切换

1.做好主从
2.在主库上创立表
	create database if not exists test;
	create table test.t1(id int);
3.在主库运转下述脚本
for i in `seq 1 1000000`
do
    mysql -e "insert into test.t1 values($i);"
    sleep 1
done
4.将某一台从库的IO线程中止,该从库的数据必定落后了
	stop slave io_thread;
5.中止主库检查切换状况
	必定不会挑选那个停掉io先从的从库当新主库,但是该从库的io线程会
	发动起来,然后指向新主库,而且数据更新到了最新

(2)根据优先级进行切换

1.装备优先级测验
	candidate_master=1
	check_repl_delay=0

6.8 为主动切换主库装备vip漂移脚本

(1)VIP漂移的两种方法

1)经过keepalived的方法,办理虚拟IP的漂移
2)经过MHA自带脚本方法,办理虚拟IP的漂移(引荐)
为了避免脑裂产生,引荐出产环境采用脚本的方法来办理虚拟vip,而不是运用 keepalived来完结。

(2)装备文件中指定脚本途径

[root@mysql-db03 ~]# vim /etc/mha/app1.cnf
[server default]
#指定主动化切换主库后,履行的vip搬迁脚本途径
master_ip_failover_script=/service/mha/master_ip_failover

(3)编写脚本

vim /service/mha/master_ip_failover

脚本首要修正以下几行

# 要求一切数据库网卡名有必要共同
my $vip = '192.168.15.250/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; 

脚本内容如下

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command,   $ssh_user,  $orig_master_host,
$orig_master_ip,$orig_master_port, $new_master_host, $new_master_ip,$new_master_port
);
#界说VIP变量
my $vip = '192.168.15.250/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; 
GetOptions(
'command=s'     => \$command,
'ssh_user=s'        => \$ssh_user,
'orig_master_host=s'    => \$orig_master_host,
'orig_master_ip=s'  => \$orig_master_ip,
'orig_master_port=i'    => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s'   => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
return 0 unless ($ssh_user);
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}

增加履行权限,不然mha无法发动

chmod +x /service/mha/master_ip_failover

(4)手动绑定vip到主库,假定此刻主库为192.168.15.100那台机器

# ssh到主库地点服务器,然后履行
ifconfig eth0:1 192.168.15.250/24  # 留意与脚本中对应eth0:1
#弥补:咱们在做keepalived的时分它会帮咱们增加VIP,实际上操作便是
	ifconfig eth0:1 192.168.15.250/24
	切换的时分便是把VIP地点机器
	ifconfig eth0:1 down
	然后切换到另一台机器去履行
	ifconfig eth0:1 192.168.15.250/24

(5)测验vip漂移

找一台主机(能够考虑在办理节点),朝着vip提交写请求

# 强调:先履行一下ssh root@192.168.15.250,把yes输入一下,退出后
# 再履行下述脚本
for i in `seq 1 1000000`
do
    ssh root@192.168.15.250 "mysql -e 'insert into test.t1 values($i);'"
    sleep 1
    echo "$i ok"
done

(6)发动MHA(假如现已发动则疏忽)

nohup masterha_manager --conf=/service/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /service/mha/manager.log 2>&1 &

(7)中止主库,测验ip漂移,并验证写操作是否中断

6.9 为手动搬迁主库装备vip漂移脚本

(1)装备文件中指定脚本途径

vim /service/mha/app1.cnf
[server default]
......
#指定手动切换主库后,履行的vip搬迁脚本途径
master_ip_online_change_script="/service/mha/master_online_change"

(2)编写手动切换主库后对应的vip搬迁脚本

vim /service/mha/master_online_change

#!/bin/bash
source /root/.bash_profile
vip=`echo '192.168.15.250/24'`  #设置VIP
key=`echo '1'`
command=`echo "$1" | awk -F = '{print $2}'`
orig_master_host=`echo "$2" | awk -F = '{print $2}'`
new_master_host=`echo "$7" | awk -F = '{print $2}'`
orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`
new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`
#要求服务的网卡识别号相同,都为eth0(这儿是)
stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ifconfig eth0:$key down"`
start_vip=`echo "ssh root@$new_master_host /usr/sbin/ifconfig eth0:$key $vip"`
if [ $command = 'stop' ]
  then
	echo -e "\n\n\n****************************\n"
	echo -e "Disabled thi VIP - $vip on old master: $orig_master_host \n"
	$stop_vip
	if [ $? -eq 0 ]
	  then
	echo "Disabled the VIP successfully"
	  else
	echo "Disabled the VIP failed"
	fi
	echo -e "***************************\n\n\n"
  fi
if [ $command = 'start' -o $command = 'status' ]
  then
	echo -e "\n\n\n*************************\n"
	echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"
	$start_vip
	if [ $? -eq 0 ]
	  then
	echo "Enabled the VIP successfully"
	  else
	echo "Enabled the VIP failed"
	fi
	echo -e "***************************\n\n\n"
fi

增加履行权限,不然mha无法发动

chmod +x /service/mha/master_online_change

(3)手动绑定vip到主库

ifconfig eth0:1 192.168.15.250

(4)手动切换主库验证vip漂移

# 先停掉mha
masterha_stop --conf=/service/mha/app1.cnf
# 将主库切换到192.168.15.101
masterha_master_switch --conf=/service/mha/app1.cnf --master_state=alive --new_master_host=192.168.15.101 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0

七 binlogserver备份

假如主库断电或许断网,binlog怎么保存?能够为MHA装备binlogserver,实时保存binglog

1) 前期预备

预备一台新的mysql实例(与主库板块共同),GTID有必要敞开。
然后改mysql主机就用于实时拉取主库的binlog,并不与主库同步,仅仅用来拉取主库的binlog,避免主库突然断电

2) 中止MHA

masterha_stop --conf=/service/mha/app1.cnf

3) 创立binlog寄存目录并设置权限

mkdir -p /bak/binlog/
chown -R mysql.mysql /bak/binlog

4)手动履行备份binlog

cd /bak/binlog
# 检查一切从库show slave status\G
mysqlbinlog  -R --host=主库ip地址 --user=mhaadmin --password=666 --raw --stop-never mysql-bin.000002 &
# 留意:写成mysql-bin.000002则会从该文件开端拉取一直到最新的
mysqlbinlog  -R --host=192.168.15.101 --user=mhaadmin --password=666 --raw --stop-never mysql-bin.000002 &

5)在app1.cnf敞开binlogserver功用

...
[binlog1]
no_master=1
# binlogserver主机的ip地址
hostname=192.168.15.102
# 不能跟当时机器数据库的binlog寄存目录相同
master_binlog_dir=/bak/binlog/

6)登录主库验证

mysql> flush logs; -- 看到binlogserver主机上/bak/binlog目录下新增日志

7)再次发动mha

nohup masterha_manager --conf=/service/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /service/mha/manager.log 2>&1 &

八 MHA脚本文件总结

在已装置的Node节点上,履行 能够检查Node装置包和Manager装置包锁包括的脚本文件;

8.1 检查Node脚本

rpm -ql mha4mysql-node-0.56-0.el6.noarch ,(这些东西一般由MHA Manager的脚本触发,无需人为操作)

8.2 检查Manager脚本

rpm -ql mha4mysql-manager-0.56-0.el6.noarch

8.3 实例脚本

九 常用指令汇总

#1、重置slave
stop slave;
reset slave;
#2、检查
SHOW SLAVE STATUS;          #检查从库仿制状况
SHOW MASTER STATUS;         #检查当时binlog位点
SHOW SLAVE HOSTS;           #检查从库列表
#3、重做slave指向主库
stop slave;
CHANGE MASTER TO MASTER_HOST='192.168.15.100', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='jason', MASTER_PASSWORD='123';
start slave;
#4、中止mha
masterha_stop --conf=/service/mha/app1.cnf
#5、检查ssh与主从状况
masterha_check_ssh --conf=/service/mha/app1.cnf
masterha_check_repl --conf=/service/mha/app1.cnf
#6、发动mha
nohup masterha_manager --conf=/service/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /service/mha/manager.log 2>&1 &
#7、检查mha状况
masterha_check_status --conf=/service/mha/app1.cnf
#8、修正mha装备文件
cat >> /service/mha/app1.cnf << EOF
[server default]
manager_log=/service/mha/manager.log
manager_workdir=/service/mha/app1
master_ip_failover_script=/service/mha/master_ip_failover
master_ip_online_change_script="/service/mha/master_online_change"
password=666
ping_interval=1
repl_password=123
repl_user=jason
ssh_port=22
ssh_user=root
user=mhaadmin
[server1]
hostname=192.168.15.100
master_binlog_dir=/var/lib/mysql
port=3306
[server2]
hostname=192.168.15.101
master_binlog_dir=/var/lib/mysql
port=3306
[server3]
hostname=192.168.15.102
master_binlog_dir=/var/lib/mysql
port=3306
EOF