首页 > 技术文章 > mha高可用

ywrj 2018-08-08 10:52 原文

MHA简介

目前在MySQL高可用方面是一个相对成熟的解决方案,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到0〜30秒之内自动完成数据库的故障切换操作,并且在进行故障切换过程中,MHA能最大程度上保证数据库的一致性,以达到真正意义上的高可用。

MHA由两部分组成MHA Manager(管理节点)和MHA Node(数据节点)MHA Manager可以独立部署在一台独立的机器上管理多个Master-Slave集群,也可以部署在一台Slave上

MHA高可用工作流程

1.复制主库binlog日志出来
2.找出relaylog日志最全的从库
3.将最全的relaylog日志在所有从库中同步(第一次数据同步)
4.将之前最全的那个从库提升为主
5.将复制出来的binlog日志,放到新提升的主库里
6.其他所有从库重新指向新提升的主库,继续主从复制

Manager工具包主要包括以下几个工具:

masterha_check_ssh #检查MHA的SSH配置状况

masterha_check_repl #检查MySQL复制状况

masterha_check_status #检测当前MHA运行状态

masterha_master_monitor #检测master是否宕机

masterha_manger #启动MHA

masterha_master_switch #控制故障转移(自动或者手动)

masterha_conf_host #添加或删除配置的server信息

masterha_secondary_check #试图建立TCP连接从远程服务器

masterha_stop #停止MHA

Node工具包主要包括以下几个工具:

save_binary_logs #保存和复制master的二进制日志

apply_diff_relay_logs #识别差异的中继日志事件

filter_mysqlbinlog #去除不必要的ROLLBACK事件

purge_relay_logs #清除中继日志

搭建mha一主双从实验环境 

 实验环境:

主机名IP地址(NAT)描述
mysql-db01 为eth0:192.168.50.149 系统:CentOS6.5(6.x都可以)安装:mysql5.6
mysql-db02 为eth0:192.168.50.151 系统:CentOS6.5(6.x都可以)安装:mysql5.6
mysql-db03 为eth0:192.168.50.152 系统:CentOS6.5(6.x都可以)安装:mysql5.6

主机名映射和关闭selinus,iptables

vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.50.149 mysql-db01      
192.168.50.151 mysql-db02
192.168.50.152 mysql-db03        #添加3台服务器的hosts域名映射

安装包准备

mha4mysql-manager-0.56.tar.gz rpm     mha4mysql-node-0.56.tar.gz      mysql-5.6.17-linux-glibc2.5-x86_64.tar.gz

安装mysql (3台都装)   

#使用mysql5.6以上版本,因为在MySQL5.6版本里多了一个GTID的功能,可以自动记录主从复制位置点的信息,并在日志中输出出来。

yum -y install ncurses-devel libaio
tar xf mysql-5.6.17-linux-glibc2.5-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/mysql-5.6.17-linux-glibc2.5-x86_64 /usr/local/mysql
useradd mysql -s /sbin/nologin -M
/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data/
/bin/cp /usr/local/mysql/support-files/my-default.cnf /etc/my.cnf
/bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
ln -s /usr/local/mysql/bin/* /usr/local/bin/
chkconfig mysqld on
/etc/init.d/mysqld start
mysqladmin -uroot password '123456'
#如对上述步骤不懂 参考mysql源码编译安装或mysql二进制安装

配置基于GTID的主从复制

必要条件

  • 主库和从库都要开启二进制日志
  • 主库和从库服务器ID不同
  • 要有主从复制用户

主库操作(mysql-db01)

#修改主库配置文件/etc/my.cnf  开启binlog 修改服务器ID以及开启gtid

vim /etc/my.cnf
[client]
socket          = /usr/local/mysql/data/mysql.sock
[mysqld]

gtid_mode
= ON          #开启gtid   此三项后边不能够有空格!!!!!! log_slave_updates            #上下两项是gtid此项为从库变主库必须开启的功能 enforce_gtid_consistency
lower_case_table_names
= 1 default-storage-engine = InnoDB port = 3306 datadir = /usr/local/mysql/data character-set-server = utf8 socket = /usr/local/mysql/data/mysql.sock
log_bin
= mysql-bin      #开启binlog日志 server_id = 1           #设置server_id
innodb_buffer_pool_size
= 200M slave-parallel-workers = 8 thread_cache_size = 600 back_log = 600 slave_net_timeout = 60 max_binlog_size = 512M key_buffer_size = 8M query_cache_size = 64M join_buffer_size = 2M sort_buffer_size = 2M query_cache_type = 1 thread_stack = 192K

#重启动MySQL服务 [root@mysql
-db01 mysql]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS!

登陆MySQL创建主从复制用户

grant replication slave on *.* to rep@'192.168.50.%' identified by '123456';
#赋予主从复制权限

从库操作(mysql-db02和mysql-db03)

#修改mysql-db02配置文件(和mysql-db01配置文件一致)
#只需要修改server-id = 1选项 和禁止mysql自动删除relaylog工能
vim /etc/my.cnf
[client] socket
= /usr/local/mysql/data/mysql.sock [mysqld] relay_log_purge = 0        #禁止mysql自动删除relaylog工能 (只在从库配置) gtid_mode = ON       #开启gtid   此三项后便不能有空格!!!!!!! log_slave_updates         #上下两项为开启gtid 此项为从库变主库必须开启的内容 enforce_gtid_consistency lower_case_table_names = 1 default-storage-engine = InnoDB port = 3306 datadir = /usr/local/mysql/data character-set-server = utf8 socket = /usr/local/mysql/data/mysql.sock
log_bin
= mysql-bin #开启binlog日志 server_id = 2 #设置server_id
innodb_buffer_pool_size
= 200M slave-parallel-workers = 8 thread_cache_size = 600 back_log = 600 slave_net_timeout = 60 max_binlog_size = 512M key_buffer_size = 8M query_cache_size = 64M join_buffer_size = 2M sort_buffer_size = 2M query_cache_type = 1 thread_stack = 192K

#重启动MySQL服务
[root@mysql-db02 mysql]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS!

在以往如果是基于二进制日志日志的主从复制,则必须要记住主库的主状态信息。

修改完配置文件以后都要重启动数据库使之生效

/etc/init.d/mysqld restart

查看GTID状态

mysql -uroot -p123456
mysql> show global variables like '%gtid%';

主库从库都必须要开启GTID,否则在做主从复制的时候就会报错。

配置主从复制(mysql-db02,mysql-db03)

mysql -uroot -p123456
mysql> change master to master_host='192.168.50.149',master_user='rep',master_password='123456',master_auto_position=1;  
                       主库IP 主库复制用户 复制用户的密码 GTID位置点自动追踪需要同步的position

开启从库的主从复制功能(mysql-db02,mysql-db03)

start slave;         #开启主从同步功能
show slave status\G;      #开看主从复制状态

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.50.149
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 447
Relay_Log_File: www-relay-bin.000002
Relay_Log_Pos: 408
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes                 #两个yes表示主从复制成功
Slave_SQL_Running: Yes                #两个yes表示主从复制成功

什么是GTID

  • GTID(全球交易)全局事务标识符:是一个唯一的标识符,它创建并与源服务器(主)上提交的每个事务相关联。此标识符不仅对其发起的服务器是唯一的,而且在给定复制设置中的所有服务器上都是唯一的。所有交易和所有GTID之间都有1对1的映射。
  • GTID实际上是由UUID + TID组成的。其中UUID是一个MySQL的实例的唯一标识.TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。

 GTID的新特性

(1)支持多线程复制:事实上是针对每个数据库开启相应的独立线程,即每个库有一个单独的(sql thread)

(2)支持启用GTID,在配置主从复制,传统的方式里,你需要找到binlog和POS点,然后将master改为指向。在mysql5.6里,无须再知道binlog和POS点,只需要知道master的IP /端口/账号密码即可,因为同步复制是自动的,MySQL的通过内部机制GTID自动找点同步。

(3)基于行复制只保存改变的列,大大节省磁盘空间,网络,内存等

(4)支持把主站和从站的相关信息记录在表中;原来是记录在文件里,现在则记录在表里,增强可用性

(5)支持延迟复制

开启方法

#上述已开启

[mysqld]
gtid_mode=ON
enforce_gtid_consistency

从库设置(mysql-db02,mysql-db03) 不让mysql管理中继日志relay log,让mha管理中继日志relay log

#登陆从库
mysql -uroot -p123456
#临时禁用自动删除relay log功能
set global relay_log_purge = 0;
#设置只读
set global read_only=1;

设置配置文件 ,在前边已做配置

部署MHA 以下mha安装可以做成yum安装包,也可tar包安装

配置环境(所有节点mysql-db01,mysql-db02,mysql-db03)

#3台MySQL都需要安装mha4mysql-node-0.56-0.el6.noarch.rpm
#光盘安装依赖包
yum -y install perl-DBD-MySQL
#安装mha4mysql-node-0.56-0.el6.noarch.rpm node节点
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm 
Preparing...                ########################################### [100%]
   1:mha4mysql-node         ########################################### [100%]
#创建mha管理账号
mysql -uroot -p123456
grant all privileges on *.* to mha@'192.168.50.%' identified by '123456';      #主库上创建从库会自动复制

部署管理节点(mha-manager)此节点部署在一个从服务器上,并且这台从服务器不会提升为主 ,会一直管理整个架构

在mysql-db03上部署管理节点

#使用阿里云源+epel源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
wget -O /etc/yum.repos.d/epel-6.repo http://mirrors.aliyun.com/repo/epel-6.repo
#安装manager依赖包(需要公网源)
yum -y install perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
#安装manager包
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm 
Preparing...                ########################################### [100%]
   1:mha4mysql-manager      ########################################### [100%]

编辑mha配置文件#创建配置文件目录

[root@mysql-db03 ~]# mkdir -p /etc/mha
#创建日志目录
[root@mysql-db03 ~]# mkdir -p /var/log/mha/mha1
#创建配置文件(默认没有)
[root@mysql-db03 ~]# cd /etc/mha/
[root@mysql-db03 mha]# ls
[root@mysql-db03 mha]# vim /etc/mha/mha1.cnf
[server default]
manager_log=/var/log/mha/mha1/manager               #manager管理日志存放路径
manager_workdir=/var/log/mha/mha1                   #manager管理日志的目录路径
master_binlog_dir=/usr/local/mysql/data             #binlog日志的存放路径
user=mha                                            #管理账户
password=123456                                     #管理账户密码
ping_interval=2                                     #存活检查的间隔时间
repl_user=rep                                       #主从复制的授权账户
repl_password=123456                                #主从复制的授权账户密码
ssh_user=root                                       #用于ssh连接的账户
[server1]
hostname=192.168.50.149                               
port=3306                                           
[server2]
#candidate_master=1                 # 注释1
#check_repl_delay=0                          # 注释2
hostname=192.168.50.151
port=3306
[server3]
hostname=192.168.50.152
port=3306
#**特别提示:**
#以上配置文件内容里每行的最后不要留有空格,因此,上述模板不能复制
# 注释1设置为候选master,如果设置该参数以后,发生主从切换以后会将此从库提升为主库,即使这个主库不是集群中事件最新的slave 
# 注释2默认情况下如果一个slave落后master 100M的relay logs 的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,
通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
配置文件模板    #次模板结尾都不带空格
[server default]
manager_log=/var/log/mha/mha1/manager
manager_workdir=/var/log/mha/mha1
master_binlog_dir=/usr/local/mysql/data
user=mha password
=123456 ping_interval=2 repl_user=rep
repl_password=123456 ssh_user
=root [server1] hostname=192.168.50.149 port=3306 [server2] hostname=192.168.50.151 port=3306 [server3] hostname=192.168.50.152 port=3306

 配置ssh信任(所有节点mysql-db01,mysql-db02,mysql-db03)

#创建密钥对       如果没有该命令 yum -y install openssh-clients  安装
[root@mysql-db03 ~]# ssh-keygen -t dsa -P "" -f ~/.ssh/id_dsa >/dev/null 2>&1
#发送mysql-db03公钥,包括自己
[root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.152
[root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.151
[root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.149
#发送mysql-db02公钥,包括自己
[root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.149
[root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.151
[root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.152
#发送mysql-db01公钥,包括自己
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.149
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.151
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.50.152

启动测试

ssh检查检测

masterha_check_ssh --conf=/etc/mha/mha1.cnf    #ssh检查命令

 在最下边出现 All SSH connection tests passed successfully.表示验证成功

主从复制检测

masterha_check_repl --conf=/etc/mha/mha1.cnf

结尾为MySQL Replication Health is OK.表示成功

错误案例:

因此在mysql-db02和mysql-db03上添加主从复制的用户即可。 

grant replication slave on *.* to rep@'192.168.50.%' identified by '123456'; 

 启动MHA

#启动
nohup masterha_manager --conf=/etc/mha/mha1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/mha1/manager.log 2>&1 &
ps -ef | grep perl | grep -v grep
root       4961   4690  0 06:33 pts/2    00:00:00 perl /usr/bin/masterha_manager --conf=/etc/mha/mha1.cnf --remove_dead_master_conf --ignore_last_failover
#说明:
nohup:启动命令
--conf:指定配置文件位置
--remove_dead_master_conf:如果有master down了,就去掉配置文件里该master的部分。

mha启动时一个后台进程 如果后台进程消失说明 主库宕机了  如果mha启动不起来说明服务有错误,当执行启动后 多按几次回车 如果不报错则说明成功

进行mha故障测试

/etc/init.d/mysqld stop      #停掉主库

查看mysql-db03上的MySQL从库同步状态

mysql -uroot -p123456 -e 'show slave status\G'

Warning: Using a password on the command line interface can be insecure.
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.50.151      #现在主库IP Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000004    #binlog日志 Read_Master_Log_Pos: 447            #binlog日志位置 Relay_Log_File: www-relay-bin.000002 Relay_Log_Pos: 408 Relay_Master_Log_File: mysql-bin.000004 Slave_IO_Running: Yes Slave_SQL_Running: Yes

查看mysql-db02上的MySQL,主库同步状态。

mysql -uroot -p123456 -e 'show master status'

Warning: Using a password on the command line interface can be insecure.
+------------------+----------+--------------+------------------+----------------------------------------------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+----------------------------------------------------------------------------------+ | mysql-bin.000005 | 231 | | | 24e5c477-9a90-11e8-8d67-000c29c53a79:1, dfd8c279-9a8f-11e8-8d66-000c29f3f2dc:1-5 | +------------------+----------+--------------+------------------+-------------------------------------------------------------------
位置为231

此时mha进程状态已经消失

ps -ef | grep perl | grep -v grep      #查询发现mha进程已经没了

查看mha配置文件信息

vim /etc/mha/mha1.cnf 
[server default]
manager_log=/var/log/mha/mha1/manager
manager_workdir=/var/log/mha/mha1
master_binlog_dir=/usr/local/mysql/data
password=123456
ping_interval=2
repl_password=123456
repl_user=rep
ssh_user=root
user=mha

#主服务器的  [server1] 标签及内容消失

[server2]
hostname=192.168.50.151
port=3306


[server3]
hostname=192.168.50.152
port=3306

当作为主库的mysql-db01上的MySQL宕机以后,mha通过检测发现mysql-db01宕机,那么会将binlog日志最全的从库立刻提升为主库,而其他的从库会指向新的主库进行再次同步。

故障还原,将曾经的主库重启并挂入架构

/etc/init.d/mysqld start
mysql -uroot -p123456
CHANGE MASTER TO MASTER_HOST='192.168.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='rep', MASTER_PASSWORD='123456'; 
#此项命令在mha服务端的/var/log/mha/mha1/manager日志里找,
start slave;        #开启主从同步
show slave status\G;    #查看同步状态
#怎样找change 语句的起始位置
cat
/var/log/mha/mha1/manager

Wed Aug 8 08:00:46 2018 - [info] mysql-bin.000004:447
Wed Aug 8 08:00:46 2018 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.50.149', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='rep', MASTER_PASSWORD='xxx';    #将密码修改 输入到故障库
Wed Aug 8 08:00:46 2018 - [info] Master Recovery succeeded. File:Pos:Exec_Gtid_Set: mysql-bin.000004, 447, 24e5c477-9a90-11e8-8d67-000c29c53a79:1,
dfd8c279-9a8f-11e8-8d66-000c29f3f2dc:1-5

将mha配置文件里缺失的部分补全

vim /etc/mha/mha1.cnf 
[server default]
manager_log=/var/log/mha/mha1/manager
manager_workdir=/var/log/mha/mha1
master_binlog_dir=/usr/local/mysql/data
password=123123
ping_interval=2
repl_password=123123
repl_user=rep
ssh_user=root
user=mha

[server1]
hostname=192.168.50.149 port=3306
[server2]
hostname=12.168.50.151 port=3306
[server3]
hostname=192.168.50.152 port=3306

启动mha进程

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

 

 

 

 

 

 

 

附录:源码安装mha的方法和yum的安装方法

节点节点的源码安装方法(node):

yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Params-Validate perl-CPAN perl-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
tar xf mha4mysql-node-0.56.tar.gz -C /usr/src/
cd /usr/src/mha4mysql-node-0.56
/perl Makefile.PL ;make;make install

manager节点的源码安装方法:

yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Params-Validate perl-CPAN perl-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
tar xf mha4mysql-manager-0.56.tar.gz -C /usr/src/cd /usr/src/mha4mysql-manager-0.56/perl Makefile.PL
make && make install

yum安装法

把所有包和依赖包放在一个文件里 createrepo -v 包目录 生成依赖关系(如果没有createrepo 可以先yum安装createrepo) 在创建repo配置文件指向该包目录yum安装

 

 

 

 

推荐阅读