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安装