kalimysql-MHA(无vip漂移版)

一、什么是MHA

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。

例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。

使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。+

最好不要把MHA Manager 放在从库上,除非能保证这个从库永远不会成为新的master

下图展示了如何通过MHA Manager管理多组主从复制。可以将MHA工作原理总结为如下:

复制代码
 1)从宕机崩溃的master保存二进制日志事件(binlog events);

(2)识别含有最新更新的slave;

(3)应用差异的中继日志(relay log)到其他的slave;

(4)应用从master保存的二进制日志事件(binlog events);

(5)提升一个slave为新的master;

(6)使其他的slave连接新的master进行复制;


MHA软件由两部分组成,Manager工具包和Node工具包,具体的说明如下。

Manager工具包主要包括以下几个工具:
masterha_check_ssh              检查MHA的SSH配置状况
masterha_check_repl             检查MySQL复制状况
masterha_manger                 启动MHA
masterha_check_status           检测当前MHA运行状态
masterha_master_monitor         检测master是否宕机
masterha_master_switch          控制故障转移(自动或者手动)
masterha_conf_host              添加或删除配置的server信息

Node工具包(这些工具通常由MHA Manager的脚本触发,无需人为操作)主要包括以下几个工具:
save_binary_logs                保存和复制master的二进制日志
apply_diff_relay_logs           识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog              去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs                清除中继日志(不会阻塞SQL线程)

二、配置

1、IP规划

2、配置1主2从环境 (我这里已经配置完毕)

复制代码
配置主从的时候需要为所有的mysql服务器 添加授权用户,后面会用到
mysql> grant replication slave on *.* to slave@'172.16.1.%' identified by '123456';

3、为所有mysql服务器增加链接文件

复制代码
[root@Master_31 ~]# ln  -s /application/mysql/bin/mysql  /usr/bin/mysql
[root@Master_31 ~]# ln  -s /application/mysql/bin/mysqlbinlog  /usr/bin/mysqlbinlog

4、所有的slave上配置

复制代码
[root@Manager_51 ~]# mysql -uroot -p123456
mysql> set global relay_log_purge = 0;          #禁用自动删除功能
mysql> set global read_only = 1;                    #从库不可写
mysql> show variables like '%read_only%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON   |
+---------------+-------+
1 row in set (0.00 sec)

[root@Manager_51 ~]# vi /etc/my.cnf        在【mysqld】标签下添加两行
relay_log_purge = 0
slave-skip-errors = 1032,1062,1107,1108,1050

配置文件跳过值介绍:

1032:记录不存在<=============================可以忽略
1062:字段值重复,入库失败<==========================可以忽略
1007:数据库已存在,创建数据库失败<=================可以忽略
1008:数据库不存在,删除数据库失败<=================可以忽略

5、所有mysql服务器安装mhamysql-node-0.56-0.el6.noarch.rpm

复制代码
[root@Master_31 ~]# cd /server/soft/
[root@Master_31 soft]# yum -y install perl-DBD-MySQL

[root@Master_31 soft]# rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm 
Preparing...                         ########################################### [100%]
   1:mha4mysql-node         ########################################### [100%]

为所有mysql服务器添加manager管理帐号
mysql> grant all privileges on *.* to mha@'172.16.1.%' identified by 'mha'; 
mysql> flush privileges;

6、manager(管理节点)配置

复制代码
(1) 安装依赖包和 mha4mysql-manager
[root@Manager_51 ~]# yum -y install perl-Config-Tiny  epel-release   perl-Log-Dispatch*   perl-Parallel-ForkManager   perl-Time-HiRes  (安装两遍)
[root@Manager_51 soft]# rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm                         
Preparing...                            ########################################### [100%]
   1:mha4mysql-manager      ########################################### [100%]

(2) 创建mha目录
[root@Manager_51 ~]# mkdir /etc/mha

(3) 创建日志目录
[root@Manager_51 ~]# mkdir -p /var/log/mha/app1


(4) 编辑manager配置文件
[root@Manager_51 ~]# vi /etc/mha/app1.conf
[server default]
manager_log=/var/log/mha/app1/manager.log            #manager管理日志
manager_workdir=/var/log/mha/app1.log                     #manager配置文件管理日志
master_binlog_dir=/application/mysql/data                  #主库binlog日志的位置
user=mha                                                                          #manager管理帐号
password=mha                                                                 #manager管理密码
ping_interval=2
repl_user=slave                                                                 #主从复制帐号
repl_password=123456                                                    #主从复制密码
ssh_user=root                                                                   #ssh远程连接用户

[server1]                                                                            #第一个主机(master)
hostname=172.16.1.31                                                     # ip
port=3306                                                                         #端口

[server2]                                                                          #第二个主机(slave)
candidate_master=1                                                      #优先的新主人(切换主库优先)
check_repl_delay=0                                                       #忽略复制延迟
hostname=172.16.1.51
port=3306


[server3]                                                                          #第三个主机(slave)
hostname=172.16.1.61
port=3306

7、所有节点生成ssh-key,并复制到其它主机(也包括自己)

复制代码
(1) 生成密钥对
[root@Master_31 ~]# ssh-keygen -t rsa

(2) 分发公钥到其它主机,包括自己
[root@Master_31 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.51

8、测试manager的同步状态并启动manager

复制代码
(1) 测试ssh
[root@Manager_51 ~]# masterha_check_ssh --conf=/etc/mha/app1.conf
Tue May 24 14:14:01 2016 - [info] All SSH connection tests passed successfully. (说明ssh连接没问题)

(2) 测试同步
[root@Manager_51 ~]# masterha_check_repl --conf=/etc/mha/app1.conf
MySQL Replication Health is OK.(说明同步配置成功)

(3) 启动MHA(manager)
[root@Manager_51 ~]# nohup  masterha_manager   --conf=/etc/mha/app1.conf  --remove_dead_master_conf   --ignore_last_failover  < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
nohub 配合 & : 让进程在后台运行

(4) 检查MHA(manager)启动状态
[root@Manager_51 ~]# masterha_check_status --conf=/etc/mha/app1.conf 
app1 (pid:7065) is running(0:PING_OK), master:172.16.1.31

9、验证主库宕机,从库(172.16.1.51)提升为主库

复制代码
(1) 登录从库mysql,查看同步状态
[root@Slave_61 ~]# mysql -uroot -p123456
主库是172.16.1.31
复制代码
(2) 在主库上操作,停掉主库
 [root@Master_31 ~]# /etc/init.d/mysqld stop

(3) 再次登录从库mysql,查看同步状态
[root@Slave_61 ~]# mysql -uroot -p123456
主库已经指定为172.16.1.51了
复制代码
(4) 查看master 上的 app1.conf  里面的主库ip已移除,而且manager的状态为   NOT RUNNING

[root@Manager_51 ~]# cat /etc/mha/app1.conf 
[server default]
manager_log=/var/log/mha/app1/manager.log
manager_workdir=/var/log/mha/app1.log
master_binlog_dir=/application/mysql/data
password=mha
ping_interval=2
repl_password=123456
repl_user=slave
ssh_user=root
user=mha

[server2]
candidate_master=1
check_repl_delay=0
hostname=172.16.1.51
port=3306

[server3]
hostname=172.16.1.61
port=3306
[root@Manager_51 ~]# masterha_check_status --conf=/etc/mha/app1.conf                                                            app1 is stopped(2:NOT_RUNNING).

10、重启原主库(172.16.1.31),并手动改为slave

master-53重启后并不能直接加入集群,需要作为slave,记录master的binlog和post,同步数据并重新跟新的master同步。(最好主库锁表,导出数据)

复制代码
(1) 同步master 
mysql> CHANGE MASTER TO MASTER_HOST='172.16.1.51',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000009',MASTER_LOG_POS=208;

(2) 修改read_only为只读
mysql> set global read_only=1; 
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%read_only%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON    |
+---------------+-------+
1 row in set (0.00 sec)

11、修改manager参数

复制代码
[root@Manager_51 ~]# cat /etc/mha/app1.conf 
[server default]
manager_log=/var/log/mha/app1/manager.log
manager_workdir=/var/log/mha/app1.log
master_binlog_dir=/application/mysql/data
password=mha
ping_interval=2
repl_password=123456
repl_user=slave
ssh_user=root
user=mha

[server1]
hostname=172.16.1.51                新的master
port=3306

[server2]
candidate_master=1                    表示备用主库
check_repl_delay=0
hostname=172.16.1.31                将原主库改为备用主库
port=3306

[server3]
hostname=172.16.1.61
port=3306

12、检查ssh 和同步情况并 重启mha进程

复制代码
(1) 测试ssh
[root@Manager_51 ~]# masterha_check_ssh --conf=/etc/mha/app1.conf
Tue May 24 14:14:01 2016 - [info] All SSH connection tests passed successfully. (说明ssh连接没问题)

(2) 测试同步
[root@Manager_51 ~]# masterha_check_repl --conf=/etc/mha/app1.conf
MySQL Replication Health is OK.(说明同步配置成功)

(3) 再次启动mha
[root@Manager_51 ~]# nohup  masterha_manager   --conf=/etc/mha/app1.conf  --remove_dead_master_conf   --ignore_last_failover  < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

(4) 查看mha状态
[root@Manager_51 ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 monitoring program is now on initialization phase(10:INITIALIZING_MONITOR). Wait for a while and try checking again.(这种情况稍等一会)

[root@Manager_51 ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 (pid:7761) is running(0:PING_OK), master:172.16.1.51

13、再把现在新的master(51) 宕掉,查172.16.1.31会恢复master身份,并且172.16.1.61 重新指向172.16.1.31为master

相关推荐
AI人工智能+电脑小能手7 小时前
【大白话说Java面试题 第85题】【Mysql篇】第15题:MySQL 的事务中,幻读是怎么解决的?
java·开发语言·数据库·mysql·面试
yoothey7 小时前
MySQL 索引小白面试详解
数据库·mysql
小陈的进阶之路8 小时前
MySQL 索引
数据库·mysql
IronMurphy8 小时前
MySQL拷打最后一讲!!!
mysql
無限進步D8 小时前
MySQL 子查询
数据库·mysql
骄马之死8 小时前
MyBatis SqlSession 与缓存机制详解
mysql·mybatis
之歆8 小时前
Day01_ES6+ 专业指南:从基础到实战的现代JavaScript开发(上)
javascript·mysql·es6
Yvonne爱编码8 小时前
数据库---Day10 索引
数据库·sql·mysql
流星白龙8 小时前
【MySQL高阶】8.MySQL系统库
android·mysql·adb
我是一颗柠檬16 小时前
【MySQL全面教学】MySQL面试高频考点汇总Day15(2026年)
数据库·后端·mysql·面试