MHA配合Atlas实现读写分离解决方案

MHA配合Atlas实现读写分离解决方案

欢迎来到 来到大浪涛天的博客

一、MHA配合Atlas实现读写分离解决方案

1. MHA的介绍

  • MHA(Master High Availability)是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。
  • 在 MySQL 故障切换过程中,MHA 能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
    MHA集群结构说明

2. Atlas中间件介绍

Atlas是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。
360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。
下载地址
https://github.com/Qihoo360/Atlas/releases

注意:
1、Atlas只能安装运行在64位的系统上
2、Centos 5.X安装 Atlas-XX.el5.x86_64.rpm,Centos 6.X安装Atlas-XX.el6.x86_64.rpm。
3、后端mysql版本应大于5.1,建议使用Mysql 5.6以上
atlas是类似于proxy这样的角色

后端atlas读写分离简图
后端atlas读写分离简图

3. MHA集群结构说明

MHA一般至少是需要3台数据库服务器,而且额外还需要一台服务器来做为Manager端。如下图所示,一般的生产应用中,Manager是用来管理多个应用数据库集群的,它只是用来监测每个应用的master端是否故障,如果故障自动进行切换,因此资源占用并不高。

3-1. 服务角色

3-1-1. MHA Manager:

通常单独部署在一台独立机器上管理多个 master/slave 集群(组),每个 master/slave 集群称作一个 application,用来管理统筹整个集群。

3-1-2. MHA node:

主要是接收管理节点所发出指令的代理,代理需要运行在每一个 mysql 节点上。简单讲 node 就是用来收集从节点服务器上所生成的 bin-log 。对比打算提升为新的主节点之上的从节点的是否拥有并完成操作,如果没有发给新主节点在本地应用后提升为主节点。每个复制组内部和 Manager 之间都需要ssh实现无密码互连,只有这样,在 Master 出故障时, Manager 才能顺利的连接进去,实现主从切换功能。

3-2. MHA提供的工具脚本

MHA会提供诸多工具程序, 其常见的如下所示:
Manager节点:mha4mysql-manager-0.56-0.el6.noarch.rpm

      masterha_check_ssh:MHA 依赖的 ssh 环境监测工具;
  masterha_check_repl:MYSQL 复制环境检测工具;
  masterga_manager:MHA 服务主程序;
  masterha_check_status:MHA 运行状态探测工具;
  masterha_master_monitor:MYSQL master 节点可用性监测工具;
  masterha_master_swith:master:节点切换工具;
  masterha_conf_host:添加或删除配置的节点;
  masterha_stop:关闭 MHA 服务的工具。

Node节点:(这些工具通常由MHA Manager的脚本触发,无需人为操作)
mha4mysql-node-0.56-0.el6.noarch.rpm

  save_binary_logs:保存和复制 master 的二进制日志;
  apply_diff_relay_logs:识别差异的中继日志事件并应用于其他 slave;
  purge_relay_logs:清除中继日志(不会阻塞 SQL 线程);

自定义扩展:

  secondary_check_script:通过多条网络路由检测master的可用性;
  master_ip_failover_script:更新application使用的masterip;
  report_script:发送报告;
  init_conf_load_script:加载初始配置参数;
  master_ip_online_change_script;更新master节点ip地址。

3-3. MHA工作原理

MHA failover的过程
MHA failover的过程

3-3-1. MHA Failover实现方式

(1) MHA通过masterha_manger脚本启动MHA的功能.

(2) 在manager启动之前,会自动检查ssh互信(masterha_check_ssh)和主从状态(masterha_check_repl)

(3) MHA-manager 通过 masterha_master_monitor脚本(每隔ping_interval秒)

(4) masterha_master_monitor探测主库3次无心跳之后,就认为主库宕机了.

(5) 进行选主过程
	算法一: 
	读取配置文件中是否有强制选主的参数?
	candidate_master=1
	check_repl_delay=0
	算法二:
	自动判断所有从库的日志量.将最接近主库数据的从库作为新主.
	算法三:
	按照配置文件先后顺序的进行选新主.

3-4. candidate_master=1 应用场景

(1) MHA+KeepAlive VIP(早期MHA架构)
(2) 多地多中心

3-5. 数据补偿

判断主库SSH的连通性
情况一: SSH能连
调用 save_binary_logs脚本,立即保存缺失部分的binlog到各个从节点,恢复
情况二: SSH无法连接
调用 apply_diff_relay_logs 脚本,计算从库的relaylog的差异,恢复到2号从库

3-6. MHA 应用透明(vip)

1. MHA会根据配置文件调用master_ip_failover.txt脚本,实现VIP的浮动。
2. 在 /etc/mha/app01.cnf中添加该脚本
  master_ip_failover_script=/usr/local/bin/master_ip_failover
3. 第一次启动需要自己手动添加vip
 [root@db01 ~]# ifconfig eth0:1 10.211.55.85/24 
 4. 业务采用VIP,当主库down后,VIP会自己切换到选的下一个master上,这样对业务来说是透明的,因为ip都一样,业务不会知道已经切换到了另外一个库上。

3-7. MHA 故障提醒

1. MHA会根据配置文件调用/usr/local/bin/send脚本,实现有故障会主动发邮件通知。
2. 在 /etc/mha/app01.cnf中添加该脚本
 report_script=/usr/local/bin/send

3-8. 设置binlog server

1. 为了最大减少数据丢失,我们可以选取一台服务器专门负责拉取主库二进制日志,而且该binlog server不进行选主,只是为了拉去binlog
2. 在配置文件中添加binlog设置
  /etc/mha/app1.cnf 
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog
3. 创建该目录,并赋予对应的权限
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/*
4. 拉取二进制日志
cd /data/mysql/binlog     -----》必须进入到自己创建好的目录
mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &
注意:
拉取日志的起点,需要按照目前主库正在使用的binlog为起点.
5.  修改完配置文件都需要进行重启mha服务
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 bin]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  < /dev/null> /var/log/mha/app1/manager.log 2>&1 &

4. Atlas的功能说明

  1. 读写分离、从库负载均衡、自动分表、IP过滤
  2. SQL语句黑白名单、DBA可平滑上下线DB、自动摘除宕机的DB
  3. 虽然是从MySQL-proxy的二次开发版本,但是优势高很多
    • 将主流程中所有Lua代码用C重写,Lua仅用于管理接口
    • 重写网络模型、线程模型
    • 实现了真正意义上的连接池
    • 优化了锁机制,性能提高数十倍

4-1. Atlas的使用场景

  1. Atlas是一个位于前端应用与后端MySQL数据库之间的中间件,它使得应用程序员无需再关心读写分离、分表等与MySQL相关的细节,可以专注于编写业务逻辑,同时使得DBA的运维工作对前端应用透明,上下线DB前端应用无感知。
  2. Atlas是一个位于应用程序与MySQL之间中间件。在后端DB看来,Atlas相当于连接它的客户端,在前端应用看来,Atlas相当于一个DB。
  3. Atlas作为服务端与应用程序通讯,它实现了MySQL的客户端和服务端协议,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节,同时为了降低MySQL负担,它还维护了连接池。

4-2. 安装部署Atlas

4-2-1. 下载安装atlas的rpm包

wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm 或者
yum -y install Atlas-2.2.1.el6.x86_64.rpm

4-2-2. 配置atlas的配置文件

4-2-2-1. 准备mha用户和repl用户的密码

atlas配置文件中的密码需要加密,可以使用,软件自带的加密工具进行加密

cd /usr/local/mysql-proxy/conf/
/usr/local/mysql-proxy/bin/encrypt  密码      ---->制作加密密码

生成所需要的mha用户和repl用户的密码

[root@db03 conf]# /usr/local/mysql-proxy/bin/encrypt admin123
lBnbdPon5VIa8s/oWZlMvQ==
[root@db03 conf]# /usr/local/mysql-proxy/bin/encrypt mha
O2jBXONX098=
4-2-2-2. 编辑配置文件
[root@db03 conf]# vi test.cnf
[mysql-proxy]
admin-username = admin
admin-password = admin123
proxy-backend-addresses = 10.211.55.81:3306
proxy-read-only-backend-addresses = 10.211.55.82:3306,10.211.55.83:3306
pwds = repl:lBnbdPon5VIa8s/oWZlMvQ==,mha:O2jBXONX098=
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060
admin-address = 0.0.0.0:2345
charset=utf8

配置文件详细的注解

1 [mysql-proxy]
 2 #(必备,默认值即可)管理接口的用户名
 3 admin-username = user
 4 #(必备,默认值即可)管理接口的密码
 5 admin-password = pwd
 6 #(必备,根据实际情况配置)主库的IP和端口
 7 proxy-backend-addresses = 192.168.0.12:3306
 8 #(非必备,根据实际情况配置)从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔。如果想让主库也能分担读请求的话,只需要将主库信息加入到下面的配置项中
 9 proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306
10 #(必备,根据实际情况配置)用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,用户名与密码之间用冒号分隔。主从数据库上需要先创建该用户并设置密码(用户名和密码在主从数据库上要一致)。比如用户名为myuser,密码为mypwd,执行./encrypt mypwd结果为HJBoxfRsjeI=。如果有多个用户用逗号分隔即可。则设置如下行所示:
11 pwds = myuser: HJBoxfRsjeI=,myuser2:HJBoxfRsjeI=
12 #(必备,默认值即可)Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true
13 daemon = true
14 #(必备,默认值即可)设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true
15 keepalive = true
16 #(必备,根据实际情况配置)工作线程数,推荐设置成系统的CPU核数
17 # 对性能和正常运行起到重要作用
18 event-threads = 4
19 #(必备,默认值即可)日志级别,分为message、warning、critical、error、debug五个级别
20 log-level = message
21 #(必备,默认值即可)日志存放的路径
22 log-path = /usr/local/mysql-proxy/log
23 #(必备,根据实际情况配置)SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,该模式下日志刷新是基于缓冲区的,当日志填满缓冲区后,才将日志信息刷到磁盘。REALTIME用于调试,代表记录SQL日志且实时写入磁盘,默认为OFF
24 sql-log = OFF
25 #(可选项,可不设置)慢日志输出设置。当设置了该参数时,则日志只输出执行时间超过sql-log-slow(单位:ms)的日志记录。不设置该参数则输出全部日志。
26 sql-log-slow = 10
27 #(可选项,可不设置)关闭不活跃的客户端连接设置。当设置了该参数时,Atlas会主动关闭经过'wait-timeout'时间后一直未活跃的连接。单位:秒
28 wait-timeout = 10
29 #(必备,默认值即可)Atlas监听的工作接口IP和端口;代表客户端应该使用1234这个端口连接Atlas来发送SQL请求。
30 proxy-address = 0.0.0.0:1234
31 #(必备,默认值即可)Atlas监听的管理接口IP和端口 ;代表DBA应该使用2345这个端口连接Atlas来执行运维管理操作。
32 admin-address = 0.0.0.0:2345
33 #(可选项,可不设置)分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项,子表需要事先建好,子表名称为表名_数字,数字范围为[0,子表数-1],如本例里,子表名称为mt_0、mt_1、mt_2
34 tables = person.mt.id.3
35 #(可选项,可不设置)默认字符集,若不设置该项,则默认字符集为latin1
36 charset = utf8
37 #(可选项,可不设置)允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
38 client-ips = 127.0.0.1, 192.168.1
39 #(可选项,极少需要)Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置
40 lvs-ips = 192.168.1.1
4-2-2-3. 启动atlas

生成启动脚本

[root@db03 ~]# cat /etc/init.d/atlasd 
 #!/bin/sh
 #
 # atlas:    Atlas Daemon
 #
 # chkconfig:    - 90 25
 # description:  Atlas Daemon
 # user:clsn
 # Blog: http://blog.nmtui.com
 # Source function library.
 
 Demo=test
 
 start()
 {
         echo -n $"Starting atlas: "
         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo start
 }
 stop()
 {
         echo -n $"Shutting down atlas: "
         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo stop
 }
 status()
 {
         echo  $"Atlas status: "
         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo status
 }
 restart()
 {
         echo $"Atlas Restart Info: "
         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo restart
 }
 
 
 ATLAS="/usr/local/mysql-proxy/bin/mysql-proxyd"
 [ -f $ATLAS ] || exit 1
 # See how we were called.
 case "$1" in
         start)
                 start
                 ;;
         stop)
                 stop
                 ;;
         restart)
                 restart
                 ;;
         status)
                 status
                 ;;
         *)
                 echo $"Usage: $0 {start|stop|restart|status}"
                 exit 1
 esac
 exit 0
 
 [root@db03 conf]# /etc/init.d/atlasd start

也可以手动启动atlas

/usr/local/mysql-proxy/bin/mysql-proxyd test start   #启动
/usr/local/mysql-proxy/bin/mysql-proxyd test stop    #停止
/usr/local/mysql-proxy/bin/mysql-proxyd test restart #重启

检查端口是否正常

[root@db03 conf]# lsof -i :33060
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2188 root   10u  IPv4 854409      0t0  TCP *:33060 (LISTEN)
[root@db03 conf]# lsof -i :2345
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2188 root    9u  IPv4 854408      0t0  TCP *:dbm (LISTEN)
4-2-2-4. Atlas的管理操作

atlas有两个端口,2345端口是管理端口,33060是业务端口。
登陆管理口

[root@db03 conf]# mysql -uadmin -padmin123 -h 10.211.55.83 -P2345

查看帮助信息

db03 [(none)]>select * from help;

查看后端代理库

db03 [(none)]>select * from backends;
+-------------+-------------------+-------+------+
| backend_ndx | address           | state | type |
+-------------+-------------------+-------+------+
|           1 | 10.211.55.81:3306 | up    | rw   |
|           2 | 10.211.55.82:3306 | up    | ro   |
|           3 | 10.211.55.83:3306 | up    | ro   |
+-------------+-------------------+-------+------+
3 rows in set (0.00 sec)

移除后端节点

db03 [(none)]>remove backend 1;
Empty set (0.01 sec)

db03 [(none)]>select * from backends;
+-------------+-------------------+-------+------+
| backend_ndx | address           | state | type |
+-------------+-------------------+-------+------+
|           1 | 10.211.55.82:3306 | up    | ro   |
|           2 | 10.211.55.83:3306 | up    | ro   |
+-------------+-------------------+-------+------+
2 rows in set (0.00 sec)

保存到配置文件中

db03 [(none)]>save config;
Empty set (0.00 sec)

将节点再添加回来

db03 [(none)]>add slave 10.211.55.81:3306;
Empty set (0.01 sec)

db03 [(none)]>save config;
Empty set (0.00 sec)

mysql生产库中创建用户app1,对测试库test具有增,查,改的权限

1. 先在mysql(master)中创建用户
db02 [(none)]>grant select,update,insert on test.* to app@'10.211.55.%' identified by 'admin123';
Query OK, 0 rows affected, 1 warning (0.01 sec)

2. 登陆atlas中,创建该用户,如
db03 [(none)]>add pwd app1:admin123;
Empty set (0.00 sec)
db03 [(none)]>select * from backends;
+-------------+-------------------+-------+------+
| backend_ndx | address           | state | type |
+-------------+-------------------+-------+------+
|           1 | 10.211.55.82:3306 | up    | ro   |
|           2 | 10.211.55.83:3306 | up    | ro   |
|           3 | 10.211.55.81:3306 | up    | ro   |
+-------------+-------------------+-------+------+

master为10.211.44.82,更改回来

db03 [(none)]>remove backend 1;
Empty set (0.00 sec)

db03 [(none)]>add master 10.211.55.82:3306;
Empty set (0.00 sec)

db03 [(none)]>
db03 [(none)]>select * from backends;
+-------------+-------------------+-------+------+
| backend_ndx | address           | state | type |
+-------------+-------------------+-------+------+
|           1 | 10.211.55.82:3306 | up    | rw   |
|           2 | 10.211.55.81:3306 | up    | ro   |
|           3 | 10.211.55.83:3306 | up    | ro   |
+-------------+-------------------+-------+------+
3 rows in set (0.00 sec)

db03 [(none)]>
db03 [(none)]>
db03 [(none)]>save config;
4-2-2-5. Atlas负载测试

atlas的33060端口是属于业务端口,连上去可以对数据库进行正常的操作。
atlas的读测试

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          81 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          83 |
+-------------+
1 row in set (0.01 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          81 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          83 |
+-------------+
1 row in set (0.00 sec)
可以看到每次查询的结果,都是两个从库轮流来读,实现来从库读。

atlas 写操作

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          82 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          82 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          82 |
+-------------+
1 row in set (0.00 sec)
当执行begin操作的时候,atlas会以为开启一个事务,是来写数据,从结果来看,每次执行都是82,实现来主库用来写,从库来读的功能

5. MHA 配合atlas 实现高可用读写分离搭建

5-1. MHA搭建环境

为了节省虚拟机,因此规划3台虚拟机来搭建,分别为DB01和DB02及DB03,其中DB01为master,因为master压力较大,因此选DB03来安装mha manger,atlas,防止mha轻易挂掉,当然正常生产环境MHA管理节点应该是独立的一个主机,如图:
MHA环境搭建

5-1-1. MHA搭建具体实施步骤

5-1-1-1. 配置关键程序软连接
ln -s /application/mysql/bin/mysqlbinlog    /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql          /usr/bin/mysql
5-1-1-2. 配置互信
#创建密钥对       如果没有该命令 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@10.211.55.81
[root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.82
[root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.83
#发送mysql-db02公钥,包括自己
[root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.81
[root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.82
[root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.83
#发送mysql-db01公钥,包括自己
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.81
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.82
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.83
5-1-1-3. 检查互信是否成功
db01:
ssh 10.211.55.81 hostname
ssh 10.211.55.82 hostname
ssh 10.211.55.83 hostname
db02:
ssh 10.211.55.81 hostname
ssh 10.211.55.82 hostname
ssh 10.211.55.83 hostname
db03:
ssh 10.211.55.81 hostname
ssh 10.211.55.82 hostname
ssh 10.211.55.83 hostname
5-1-1-4. 安装软件包(所有节点)
yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
5-1-1-5. 基于GTID配置主从同步:
  1. 准备环境
pkill mysqld

m -rf /data/mysql/data/*

m -rf /data/binlog/*
  1. 准备配置文件

主库db01:


cat > /etc/my.cnf <<EOF
[mysqld]
basedir=/application/mysql/
datadir=/data/mysql/data
socket=/tmp/mysql.sock
server_id=81
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db01 [\d]>
EOF

slave1(db02):

cat > /etc/my.cnf <<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/mysql/data
socket=/tmp/mysql.sock
server_id=82
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db02 [\d]>
EOF

slave2(db03):

cat > /etc/my.cnf <<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/mysql/data
socket=/tmp/mysql.sock
server_id=83
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db03 [\d]>
EOF
  1. 创建用户
useradd -s /sbin/nologin mysql
  1. 创建必须的目录
mkdir -p /data/binlog/
mkdir -p /data/mysql/data
chown -R mysql.mysql /data
  1. 初始化数据
mysqld --initialize-insecure --user=mysql --basedir=/application/mysql  --datadir=/data/mysql/data 
  1. 启动路径systemctl启动
cat >/etc/systemd/system/mysqld.service <<EOF
   [Unit]
   Description=MySQL Server
   Documentation=man:mysqld(8)
   Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
   After=network.target
   After=syslog.target
   [Install]
   WantedBy=multi-user.target
   [Service]
   User=mysql
   Group=mysql
   ExecStart=/application/mysql/bin/mysqld --defaults-file=/etc/my.cnf
   LimitNOFILE = 5000
 EOF
  1. 复制启动脚本 /etc/init.d/mysqld start启动
 cp /application/mysql/support-files/mysql.server  /etc/init.d/mysqld
 修改一下
 basedir=/application/mysql
 datadir=/data/mysql/data
  1. 启动数据库
/etc/init.d/mysqld start
  1. 构建主从:
master:81
slave:82,83

81:
grant replication slave  on *.* to repl@'10.211.55.%' identified by 'admin123';

8283:
change master to 
master_host='10.211.55.81',
master_user='repl',
master_password='admin123' ,
MASTER_AUTO_POSITION=1;
start slave;
5-1-1-6. 在db01主库中创建mha需要的用户
grant all privileges on *.* to mha@'10.211.55.%' identified by 'mha';
5-1-1-7. Manager软件安装(db03)
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
5-1-1-7-1. 配置文件准备(db03)
	创建配置文件目录
 mkdir -p /etc/mha
	创建日志目录
 mkdir -p /var/log/mha/app1
	编辑mha配置文件
cat > /etc/mha/app1.cnf <<EOF
[server default]
manager_log=/var/log/mha/app1/manager        
manager_workdir=/var/log/mha/app1            
master_binlog_dir=/data/binlog       
user=mha                                   
password=mha                               
ping_interval=2
repl_password=admin123
repl_user=repl
ssh_user=root                               
[server1]                                   
hostname=10.211.55.81
port=3306                                  
[server2]            
hostname=10.211.55.82
port=3306
[server3]
hostname=10.211.55.83
port=3306
EOF
5-1-1-8. MHA 应用透明(vip)-db03
cp /root/master_ip_failover.txt /usr/local/bin/master_ip_failover

vim /usr/local/bin/master_ip_failover
my $vip = '10.211.55.85/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

[root@db03 bin]# chmod +x /usr/local/bin/master_ip_failover
[root@db03 bin]# yum install -y  dos2unix
[root@db03 bin]# dos2unix /usr/local/bin/master_ip_failover 

[root@db03 bin]# vim /etc/mha/app1.cnf 
master_ip_failover_script=/usr/local/bin/master_ip_failover

db01:手工添加vip
[root@db01 ~]# ifconfig eth0:1 10.211.55.85/24
5-1-1-9. MHA 故障提醒
[root@db03 ~]# cp -a email/* /usr/local/bin/
[root@db03 ~]# cd /usr/local/bin/
[root@db03 ]# chmod +x *

[root@db03 bin]# vim /etc/mha/app1.cnf 
report_script=/usr/local/bin/send
5-1-1-10. 额外的数据补偿(binlog_server)
找一台额外的机器,必须要有5.6以上的版本,支持gtid并开启,我们直接用的第二个slave(db03)

vim /etc/mha/app1.cnf 
[binlog1]
no_master=1
hostname=10.211.55.83
master_binlog_dir=/data/mysql/binlog

(2) 创建必要目录
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/*

(3) 拉取主库binlog日志

cd /data/mysql/binlog     -----》必须进入到自己创建好的目录
mysqlbinlog  -R --host=10.211.55.81 --user=mha --password=mha --raw  --stop-never mysql-bin.000002 &

注意:
拉取日志的起点,需要按照目前主库正在使用的binlog为起点.
5-1-1-11. 状态检查及开启MHA(db03)
 masterha_check_ssh  --conf=/etc/mha/app1.cnf 
 masterha_check_repl  --conf=/etc/mha/app1.cnf 
 
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
5-1-1-12. 查看MHA状态
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:10074) is running(0:PING_OK), master:10.211.55.81

6. MHA故障模拟及恢复处理

6-1. 宕掉 db01 数据库

[root@db01 ~]# /etc/init.d/mysqld stop
过了5秒后查看db02数据库看看vip是否已经飘过来了
[root@db02 ~]# ifconfig -a |grep -A3 eth0:1
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.211.55.85  netmask 255.255.255.0  broadcast 10.211.55.255
        ether 00:1c:42:06:3d:8f  txqueuelen 1000  (Ethernet)

6-2. 安装atlas

6-2-1. 下载安装atlas的rpm包

wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm 或者
yum -y install Atlas-2.2.1.el6.x86_64.rpm

6-2-2. 配置atlas的配置文件

6-2-2-1. 准备mha用户和repl用户的密码

atlas配置文件中的密码需要加密,可以使用,软件自带的加密工具进行加密

cd /usr/local/mysql-proxy/conf/
/usr/local/mysql-proxy/bin/encrypt  密码      ---->制作加密密码

生成所需要的mha用户和repl用户的密码

[root@db03 conf]# /usr/local/mysql-proxy/bin/encrypt admin123
lBnbdPon5VIa8s/oWZlMvQ==
[root@db03 conf]# /usr/local/mysql-proxy/bin/encrypt mha
O2jBXONX098=
6-2-2-2. 编辑配置文件
[root@db03 conf]# vi test.cnf
[mysql-proxy]
admin-username = admin
admin-password = admin123
proxy-backend-addresses = 10.211.55.81:3306
proxy-read-only-backend-addresses = 10.211.55.82:3306,10.211.55.83:3306
pwds = repl:lBnbdPon5VIa8s/oWZlMvQ==,mha:O2jBXONX098=
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060
admin-address = 0.0.0.0:2345
charset=utf8

启动atlas

/usr/local/mysql-proxy/bin/mysql-proxyd test start   #启动
/usr/local/mysql-proxy/bin/mysql-proxyd test stop    #停止
/usr/local/mysql-proxy/bin/mysql-proxyd test restart #重启

检查端口是否正常

[root@db03 conf]# lsof -i :33060
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2188 root   10u  IPv4 854409      0t0  TCP *:33060 (LISTEN)
[root@db03 conf]# lsof -i :2345
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2188 root    9u  IPv4 854408      0t0  TCP *:dbm (LISTEN)

6-2-3. 安装完测试

atlas的33060端口是属于业务端口,连上去可以对数据库进行正常的操作。
atlas的读测试

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          81 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          83 |
+-------------+
1 row in set (0.01 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          81 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          83 |
+-------------+
1 row in set (0.00 sec)
可以看到每次查询的结果,都是两个从库轮流来读,实现来从库读。

atlas 写操作

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          82 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          82 |
+-------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          82 |
+-------------+
1 row in set (0.00 sec)
当执行begin操作的时候,atlas会以为开启一个事务,是来写数据,从结果来看,每次执行都是82,实现来主库用来写,从库来读的功能
原文地址:https://www.cnblogs.com/chacha51/p/13823811.html