• 欢迎访问蜷缩的蜗牛博客 蜷缩的蜗牛
  • 微信搜索: 蜷缩的蜗牛 | 联系站长 kbsonlong@qq.com
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

MHA高可用架构与Atlas读写分离

Mysql 蜷缩的蜗牛 6个月前 (03-30) 65次浏览 已收录

1.1 MHA 简介

1.1.1 MHA 软件介绍

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

  MHA 能够在较短的时间内实现自动故障检测和故障转移,通常在 10-30 秒以内;在复制 框架中,MHA 能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的 replication 中添加额外的服务器,仅需要一个 manager 节点,而一个 Manager 能管理多套复制,所以能大大地节约服务器的数量;另外,安装简单,无性能损耗,以及不需要修改现 有的复制部署也是它的优势之处。

  MHA 还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中 (通过将从库提升为主库),大概0.5-2 秒内即可完成。

  该软件由两部分组成: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已经支持一主一从。

1.1.2 MHA 工作原理

 

工作原理说明:

 

   1、保存 master 上的所有 binlog 事件

    2、找到含有最新 binlog 位置点的 slave

    3、通过中继日志将数据恢复到其他的 slave

    4、将包含最新 binlog 位置点的 slave 提升为 master

    5、将其他从库 slave 指向新的 master 原 slave01 并开启主从复制

    6、将保存下来的 binlog 恢复到新的 master 上

 

1、监控所有 node 节点MHA 功能说明:

2、自动故障切换(failover)

     前提是必须有三个节点存在,并且有两个从库

      (1)选主前提,按照配置文件的顺序进行,但是如果此节点后主库 100M 以上 relay-log 就不会选

      (2)如果你设置了权重,总会切换带此节点;一般在多地多中心的情况下,一般会把权重设置在本地节点。

      (3)选择 s1 为新主

      (4)保存主库 binlog 日志

3、重新构建主从

      (1)将有问题的节点剔除 MHA

          进行第一阶段数据补偿,S2 缺失部分补全 90

      (2)s1 切换角色为新主,将 s2 指向新主 S1

            s2  change master to s1

      (3) 第二阶段数据补偿

            将保存过来的新主和原有主缺失部分的 binlog,应用到新主。

      (4)虚拟 IP 漂移到新主,对应用透明无感知

      (5)通知管理员故障切换

1.1.3 MHA 高可用架构图

 

1.1.4 MHA 工具介绍

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

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

masterha_check_ssh             #检査 MHA 的 ssh-key^
masterha_check_repl            #检査主从复制情况
masterha_manger                #启动 MHA
masterha_check_status          #检测 MHA 的运行状态^
masterha_mast er_monitor       #检测 master 是否宕机一
masterha_mast er_switch        #手动故障转移—
masterha_conf_host             #手动添加 server 倍息一
masterha_secondary_check       #建立 TCP 连接从远程服务器 v
masterha_stop                  #停止 MHA

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

save_binary_1ogs       #保存宕机的 master 的 binlog
apply_diff_relay_logs   #识别 relay log 的差异
filter_mysqlbinlog           #防止回滚事件一 MHA 已不再使用这个工具
purge_relay_logs           #清除中继曰志一不会阻塞 SQL 线程

1.1.5 MHA 的优点

1、自动故障转移

2、主库崩溃不存在数据不一致的情况

3、不需要对当前的 mysql 环境做重大修改

4、不需要添加额外的服务器

5、性能优秀,可以工作再半同步和异步复制框架

6、只要 replication 支持的存储引擎 mha 都支持

1.2 环境说明

   在本次的实验中,共需要用到三台主机,系统、软件说明如下。

1.2.1 系统环境说明

db01 主机(master)

[root@db01 ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)
[root@db01 ~]# uname -r
2.6.32-696.el6.x86_64
[root@db01 ~]# /etc/init.d/iptables status
iptables: Firewall is not running.
[root@db01 ~]# getenforce 
Disabled
[root@db01 ~]# hostname -I
10.0.0.51 172.16.1.51

db02 主机(slave1)

 1 [root@db02 ~]# cat /etc/redhat-release 
 2 CentOS release 6.9 (Final)
 3 [root@db02 ~]# uname -r
 4 2.6.32-696.el6.x86_64
 5 [root@db02 ~]# /etc/init.d/iptables status
 6 iptables: Firewall is not running.
 7 [root@db02 ~]# getenforce 
 8 Disabled
 9 [root@db02 ~]# hostname -I
10 10.0.0.52 172.16.1.52

View Code db02 主机环境说明 

db03 主机(slave1,MHA Manages、Atlas 节点)

 1 [root@db03 ~]# cat /etc/redhat-release 
 2 CentOS release 6.9 (Final)
 3 [root@db03 ~]# uname -r
 4 2.6.32-696.el6.x86_64
 5 [root@db03 ~]# /etc/init.d/iptables status
 6 iptables: Firewall is not running.
 7 [root@db03 ~]# getenforce 
 8 Disabled
 9 [root@db03 ~]# hostname -I
10 10.0.0.53 172.16.1.53

View Code  db03 主机环境说明 

1.2.2 mysql 软件说明

         三台服务器上都全新安装 mysql 5.6.36 :

[root@db01 ~]# mysql --version
mysql  Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using  EditLine wrapper

  关于 mysql 数据库具体的安装方法参考:http://www.cnblogs.com/clsn/p/8038964.html#_label3

1.3 基于 GTID 的主从复制配置

1.3.1 先决条件

  ? 主库和从库都要开启 binlog

  ? 主库和从库 server-id 必须不同

  ? 要有主从复制用户

1.3.2 配置主从复制

db01 my.cnf文件

[root@db01 ~]# cat /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log-bin=/data/mysql/mysql-bin
binlog_format=row
secure-file-priv=/tmp 
server-id=51
skip-name-resolve  # 跳过域名解析
gtid-mode=on    # 启用 gtid 类型,否则就是普通的复制架构
enforce-gtid-consistency=true    #强制 GTID 的一致性
log-slave-updates=1     # slave 更新是否记入日志(5.6 必须的)
relay_log_purge = 0 
[mysql]
socket=/tmp/mysql.sock

db02 my.cnf文件

 1 [root@db02 ~]# cat /etc/my.cnf
 2 [mysqld]
 3 basedir=/application/mysql
 4 datadir=/application/mysql/data
 5 socket=/tmp/mysql.sock
 6 log-error=/var/log/mysql.log
 7 log-bin=/data/mysql/mysql-bin
 8 binlog_format=row
 9 secure-file-priv=/tmp 
10 server-id=52
11 skip-name-resolve
12 gtid-mode=on
13 enforce-gtid-consistency=true
14 log-slave-updates=1
15 relay_log_purge = 0 
16 [mysql]
17 socket=/tmp/mysql.sock

View Code db02 my.cnf文件 

db03 my.cnf文件

 1 [root@db03 ~]# cat /etc/my.cnf
 2 [mysqld]
 3 basedir=/application/mysql
 4 datadir=/application/mysql/data
 5 socket=/tmp/mysql.sock
 6 log-error=/var/log/mysql.log
 7 log-bin=/data/mysql/mysql-bin
 8 binlog_format=row
 9 secure-file-priv=/tmp 
10 server-id=53
11 skip-name-resolve
12 gtid-mode=on
13 enforce-gtid-consistency=true
14 log-slave-updates=1
15 relay_log_purge = 0 
16 skip-name-resolve
17 [mysql]
18 socket=/tmp/mysql.sock

View Code db03 my.cnf 文件

创建复制用户 (51 作为主节点,52、53 为从)

GRANT REPLICATION SLAVE ON *.* TO repl@'10.0.0.%' IDENTIFIED BY '123';

从库开启复制

change master to 
    master_host='10.0.0.51',
    master_user='repl',
    master_password='123',
    MASTER_AUTO_POSITION=1;

启动从库复制

start slave;

1.3.3 GTID 复制技术说明

MySQL GTID简介

  GTID 的全称为 global transaction identifier ,可以翻译为全局事务标示符,GTID 在原始 master 上的事务提交时被创建。GTID 需要在全局的主-备拓扑结构中保持唯一性,GTID 由两部分组成:

   GTID = source_id:transaction_id 

  source_id用于标示源服务器,用 server_uuid 来表示,这个值在第一次启动时生成,并写入到配置文件 data/auto.cnf 中

  transaction_id则是根据在源服务器上第几个提交的事务来确定。

GTID事件结构

 

GTID在二进制日志中的结构

 4

一个 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 来确定新备库复制坐标。

    GTID 是用来替代以前 classic 的复制方法;

    MySQL5.6.2 支持 MySQL5.6.10 后完善;

GTID相比传统复制的优点:

1.一个事务对应一个唯一 ID,一个 GTID 在一个服务器上只会执行一次

2.GTID 是用来代替传统复制的方法,GTID 复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置

3.减少手工干预和降低服务故障时间,当主机挂了之后通过软件从众多的备机中提升一台备机为主机

GTID的限制:

1.不支持非事务引擎

2.不支持 create table … select 语句复制(主库直接报错)

  原理:( 会生成两个 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

1.3.4 COM_BINLOG_DUMP_GTID

从机发送到主机执行的事务的标识符的主范围

   Master send all other transactions to slave 

  同样的 GTID 不能被执行两次,如果有同样的 GTID,会自动被 skip 掉。

 

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

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

GTID组成

  GTID 实际上是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例上已经提交的事务数量,并且随着事务提交单调递增

GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29

1.3.5 【示例二】MySQL GTID 复制配置

主节点 my.cnf 文件

# vi /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
server-id=1
log-bin=mysql-bin
socket=/tmp/mysql.sock
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

从节点 my.cnf 文件

# vi /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
server-id=2
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true
log-bin=mysql-bin
log_slave_updates = 1
socket=/tmp/mysql.sock

配置文件注解

server-id=x                    # 同一个复制拓扑中的所有服务器的 id 号必须惟一
binlog-format=RO               # 二进制日志格式,强烈建议为 ROW
gtid-mode=on                   # 启用 gtid 类型,否则就是普通的复制架构
enforce-gtid-consistency=true  # 强制 GTID 的一致性
log-slave-updates=1            # slave 更新是否记入日志

  复制用户准备(Master 主节点)

mysql>GRANT REPLICATION SLAVE ON *.* TO rep@'10.0.0.%' IDENTIFIED BY '123';

  开启复制(Slave 从节点)

mysql>start slave;
mysql>show slave status\G

  现在就可以进行主从复制测试。

1.4 部署 MHA

  本次 MHA 的部署基于 GTID 复制成功构建,普通主从复制也可以构建 MHA 架构。

1.4.1 环境准备(所有节点操作)

安装依赖包

yum install perl-DBD-MySQL -y

    下载 mha 软件,mha 官网:https://code.google.com/archive/p/mysql-master-ha/

         github 下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

下载软件包

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

mha4mysql-manager-0.56.tar.gz

mha4mysql-node-0.56-0.el6.noarch.rpm

mha4mysql-node-0.56.tar.gz

在所有节点安装 node

rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

创建 mha 管理用户

grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';

# 主库上创建,从库会自动复制(在从库上查看)

  创建命令软连接(重要)

  如果不创建命令软连接,检测 mha 复制情况的时候会报错

ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql /usr/bin/mysql

1.4.2 部署管理节点(mha-manager)

在 mysql-db03 上部署管理节点

# 安装 epel 源,软件需要
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo 
# 安装 manager 依赖包
yum install -y 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

创建必须目录

mkdir -p /etc/mha
mkdir -p /var/log/mha/app1    ----》可以管理多套主从复制

编辑 mha-manager配置文件

[root@db03 ~]# cat  /etc/mha/app1.cnf
[server default]                        
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/mysql
user=mha
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

【配置文件详解】

 1 [server default]
 2 #设置 manager 的工作目录
 3 manager_workdir=/var/log/masterha/app1
 4 #设置 manager 的日志
 5 manager_log=/var/log/masterha/app1/manager.log 
 6 #设置 master 保存 binlog 的位置,以便 MHA 可以找到 master 的日志,我这里的也就是 mysql 的数据目录
 7 master_binlog_dir=/data/mysql
 8 #设置自动 failover 时候的切换脚本
 9 master_ip_failover_script= /usr/local/bin/master_ip_failover
10 #设置手动切换时候的切换脚本
11 master_ip_online_change_script= /usr/local/bin/master_ip_online_change
12 #设置 mysql 中 root 用户的密码,这个密码是前文中创建监控用户的那个密码
13 password=123456
14 #设置监控用户 root
15 user=root
16 #设置监控主库,发送 ping 包的时间间隔,尝试三次没有回应的时候自动进行 failover
17 ping_interval=1
18 #设置远端 mysql 在发生切换时 binlog 的保存位置
19 remote_workdir=/tmp
20 #设置复制用户的密码
21 repl_password=123456
22 #设置复制环境中的复制用户名 
23 repl_user=rep
24 #设置发生切换后发送的报警的脚本
25 report_script=/usr/local/send_report
26 #一旦 MHA 到 server02 的监控之间出现问题,MHA Manager 将会尝试从 server03 登录到 server02
27 secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02 --user=root --master_host=server02 --master_ip=10.0.0.51 --master_port=3306
28 #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂,这里没有使用)
29 shutdown_script=""
30 #设置 ssh 的登录用户名
31 ssh_user=root 
32 
33 [server1]
34 hostname=10.0.0.51
35 port=3306
36 
37 [server2]
38 hostname=10.0.0.52
39 port=3306
40 #设置为候选 master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的 slave
41 candidate_master=1
42 #默认情况下如果一个 slave 落后 master 100M 的 relay logs 的话,MHA 将不会选择该 slave 作为一个新的 master,因为对于这个 slave 的恢复需要花费很长时间,通过设置 check_repl_delay=0,MHA 触发切换在选择一个新的 master 的时候将会忽略复制延时,这个参数对于设置了 candidate_master=1 的主机非常有用,因为这个候选主在切换的过程中一定是新的 master
43 check_repl_delay=0

View Code 配置文件详细说明

配置 ssh 信任(密钥分发,在所有节点上执行)

# 生成密钥
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
# 分发公钥,包括自己
for i in 1 2 3 ;do ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.5$i ;done

         分发完成后测试分发是否成功

for i in 1 2 3 ;do ssh 10.0.0.5$i  date ;done
或
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
最后一行信息为如下字样即为分发成功:
Thu Dec 28 18:44:53 2017 - [info] All SSH connection tests passed successfully.

1.4.3 启动 mha

经过上面的部署过后,mha 架构已经搭建完成

# 启动 mha
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 &

         启动成功后,检查主库状态

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:3298) is running(0:PING_OK), master:10.0.0.51

1.4.4 切换 master 测试

查看现在的主库是哪个

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:11669) is running(0:PING_OK), master:10.0.0.51

手动停止主库

[root@db01 ~]# /etc/init.d/mysqld stop 
Shutting down MySQL..... SUCCESS!

再停止数据的同时查看日志信息的变化

[root@db03 ~]# tailf /var/log/mha/app1/manager
~~~
Fri Dec 29 15:51:14 2017 - [info]  All other slaves should start replication from
here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';

修复主从

①  启动原主库,添加 change master to 信息

[root@db01 ~]# /etc/init.d/mysqld start 
Starting MySQL. SUCCESS!
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';
mysql> start slave;

②  查看主从复制状态

mysql> show slave status\G
                   Master_Host: 10.0.0.52
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

修复 mha

①  修改 app1.cnf 配置文件,添加回被剔除主机

[root@db03 ~]# cat  /etc/mha/app1.cnf 
[binlog1]
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog/
no_master=1

[server default]
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/mysql
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root
user=mha

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

②  mha 检查复制状态

[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

③  启动 mha 程序

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 &

到此主库切换成功

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:11978) is running(0:PING_OK), master:10.0.0.52

实验结束将主库切换回 db01.

①  停止 mha

[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf 
Stopped app1 successfully.

②  停止所有从库 slave(所有库操作)

stop slave;
reset slave all;

③  重做主从复制(db02、db03)

CHANGE MASTER TO 
  MASTER_HOST='10.0.0.51', 
  MASTER_PORT=3306, 
  MASTER_AUTO_POSITION=1, 
  MASTER_USER='repl', 
  MASTER_PASSWORD='123';

④  启动 slave

start slave;

                  启动之后检查从库是否为两个 yes  show slave status\G 

⑤  mha 检查主从复制

[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

⑥  启动 mha

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 &

  检查切换是否成功

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:12127) is running(0:PING_OK), master:10.0.0.51

         到此主主节点有切回到 db01

1.4.5 设置权重

修改[server1]的权重

[server1]
hostname=10.0.0.51
port=3306
candidate_master=1
check_repl_delay=0

配置说明

candidate_master=1                  ----》不管怎样都切到优先级高的主机,一般在主机性能差异的时候用           
check_repl_delay=0                  ----》不管优先级高的备选库,数据延时多久都要往那切

注:

1、多地多中心,设置本地节点为高权重

2、在有半同步复制的环境中,设置半同步复制节点为高权重

3、你觉着哪个机器适合做主节点,配置较高的 、性能较好的

1.5 配置 VIP 漂移

1.5.1 IP 漂移的两种方式

   ? 通过 keepalived 的方式,管理虚拟 IP 的漂移

   ?  通过 MHA 自带脚本方式,管理虚拟 IP 的漂移

1.5.2 MHA 脚本方式

修改 mha配置文件

[root@db03 ~]# grep "script" /etc/mha/app1.cnf 
[server default]
master_ip_failover_script=/usr/local/bin/master_ip_failover

         再主配置中添加 VIP 脚本

脚本内容

[root@db03 ~]# cat /usr/local/bin/master_ip_failover 
#!/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
);
my $vip = '10.0.0.55/24';
my $key = '0';
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";
}

View Code VIP 管理脚本 

  该脚本为软件自带,脚本获取方法:再 mha源码包中的 samples目录下有该脚本的模板,对该模板进行修改即可使用。路径如: mha4mysql-manager-0.56/samples/scripts 

  脚本修改内容

my $vip = '10.0.0.55/24';
my $key = '0';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

脚本添加执行权限否则 mha 无法启动

chmod +x /usr/local/bin/master_ip_failover

手动绑定 VIP(主库)

ifconfig eth0:0 10.0.0.55/24

  检查

[root@db01 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:6c:7a:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fe6c:7a11/64 scope link 
       valid_lft forever preferred_lft forever

         至此 vip漂移配置完成 

1.5.3 测试虚拟 IP 漂移

查看 db02 的 slave 信息

 1 mysql> show slave status\G
 2 *************************** 1. row ***************************
 3                Slave_IO_State: Waiting for master to send event
 4                   Master_Host: 10.0.0.51
 5                   Master_User: repl
 6                   Master_Port: 3306
 7                 Connect_Retry: 60
 8               Master_Log_File: mysql-bin.000007
 9           Read_Master_Log_Pos: 191
10                Relay_Log_File: db02-relay-bin.000002
11                 Relay_Log_Pos: 361
12         Relay_Master_Log_File: mysql-bin.000007
13              Slave_IO_Running: Yes
14             Slave_SQL_Running: Yes
15               Replicate_Do_DB: 
16           Replicate_Ignore_DB: 
17            Replicate_Do_Table: 
18        Replicate_Ignore_Table: 
19       Replicate_Wild_Do_Table: 
20   Replicate_Wild_Ignore_Table: 
21                    Last_Errno: 0
22                    Last_Error: 
23                  Skip_Counter: 0
24           Exec_Master_Log_Pos: 191
25               Relay_Log_Space: 564
26               Until_Condition: None
27                Until_Log_File: 
28                 Until_Log_Pos: 0
29            Master_SSL_Allowed: No
30            Master_SSL_CA_File: 
31            Master_SSL_CA_Path: 
32               Master_SSL_Cert: 
33             Master_SSL_Cipher: 
34                Master_SSL_Key: 
35         Seconds_Behind_Master: 0
36 Master_SSL_Verify_Server_Cert: No
37                 Last_IO_Errno: 0
38                 Last_IO_Error: 
39                Last_SQL_Errno: 0
40                Last_SQL_Error: 
41   Replicate_Ignore_Server_Ids: 
42              Master_Server_Id: 51
43                   Master_UUID: c8fcd56e-eb79-11e7-97b0-000c296c7a11
44              Master_Info_File: /application/mysql-5.6.36/data/master.info
45                     SQL_Delay: 0
46           SQL_Remaining_Delay: NULL
47       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
48            Master_Retry_Count: 86400
49                   Master_Bind: 
50       Last_IO_Error_Timestamp: 
51      Last_SQL_Error_Timestamp: 
52                Master_SSL_Crl: 
53            Master_SSL_Crlpath: 
54            Retrieved_Gtid_Set: 
55             Executed_Gtid_Set: c8fcd56e-eb79-11e7-97b0-000c296c7a11:1-3
56                 Auto_Position: 1
57 1 row in set (0.00 sec)

View Code 现在主从状态

停掉主库

[root@db01 ~]# /etc/init.d/mysqld stop

在 db03 上查看从库 slave 信息

 1 mysql>  show slave status\G
 2 *************************** 1. row ***************************
 3                Slave_IO_State: Waiting for master to send event
 4                   Master_Host: 10.0.0.52
 5                   Master_User: repl
 6                   Master_Port: 3306
 7                 Connect_Retry: 60
 8               Master_Log_File: mysql-bin.000009
 9           Read_Master_Log_Pos: 191
10                Relay_Log_File: db03-relay-bin.000002
11                 Relay_Log_Pos: 361
12         Relay_Master_Log_File: mysql-bin.000009
13              Slave_IO_Running: Yes
14             Slave_SQL_Running: Yes
15               Replicate_Do_DB: 
16           Replicate_Ignore_DB: 
17            Replicate_Do_Table: 
18        Replicate_Ignore_Table: 
19       Replicate_Wild_Do_Table: 
20   Replicate_Wild_Ignore_Table: 
21                    Last_Errno: 0
22                    Last_Error: 
23                  Skip_Counter: 0
24           Exec_Master_Log_Pos: 191
25               Relay_Log_Space: 564
26               Until_Condition: None
27                Until_Log_File: 
28                 Until_Log_Pos: 0
29            Master_SSL_Allowed: No
30            Master_SSL_CA_File: 
31            Master_SSL_CA_Path: 
32               Master_SSL_Cert: 
33             Master_SSL_Cipher: 
34                Master_SSL_Key: 
35         Seconds_Behind_Master: 0
36 Master_SSL_Verify_Server_Cert: No
37                 Last_IO_Errno: 0
38                 Last_IO_Error: 
39                Last_SQL_Errno: 0
40                Last_SQL_Error: 
41   Replicate_Ignore_Server_Ids: 
42              Master_Server_Id: 52
43                   Master_UUID: c8fa1d13-eb79-11e7-97b0-000c29d60ab3
44              Master_Info_File: /application/mysql-5.6.36/data/master.info
45                     SQL_Delay: 0
46           SQL_Remaining_Delay: NULL
47       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
48            Master_Retry_Count: 86400
49                   Master_Bind: 
50       Last_IO_Error_Timestamp: 
51      Last_SQL_Error_Timestamp: 
52                Master_SSL_Crl: 
53            Master_SSL_Crlpath: 
54            Retrieved_Gtid_Set: 
55             Executed_Gtid_Set: c8fcd56e-eb79-11e7-97b0-000c296c7a11:1-3
56                 Auto_Position: 1
57 1 row in set (0.00 sec)

View Code 停掉主库后的主从信息

在 db01 上查看 vip 信息

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:6c:7a:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    inet6 fe80::20c:29ff:fe6c:7a11/64 scope link 
       valid_lft forever preferred_lft forever

在 db02 上查看 vip 信息

 [root@db02 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d6:0a:b3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.52/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fed6:ab3/64 scope link 
       valid_lft forever preferred_lft forever

         至此,VIP 漂移就测试成功

1.6 配置 binlog-server

1.6.1 配置 binlog-server

1)前期准备:

1、准备一台新的 mysql 实例(db03),GTID 必须开启。

2、将来 binlog 接收目录,不能和主库 binlog 目录一样

2)停止 mha

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

3)在 app1.cnf 开启 binlogserver 功能

    [binlog1]
    no_master=1
    hostname=10.0.0.53                         ----> 主机 DB03
    master_binlog_dir=/data/mysql/binlog/  ----> binlog 保存目录

4)开启 binlog 接收目录,注意权限

mkdir -p /data/mysql/binlog/ 
chown -R mysql.mysql /data/mysql
# 进入目录启动程序
  cd /data/mysql/binlog/ &&\
  mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &

  参数说明:-R 远程主机

5)启动 mha

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 &

1.6.2 测试 binlog 备份

#查看 binlog 目录中的 binlog

[root@db03 binlog]# ll
total 44
-rw-r--r-- 1 root root 285 Mar  8 03:11 mysql-bin.000001

#登录主库

[root@mysql-db01 ~]# mysql -uroot -p123

#刷新 binlog

mysql> flush logs;

#再次查看 binlog 目录

[root@db03 binlog]# ll
total 48
-rw-r--r-- 1 root root 285 Mar  8 03:11 mysql-bin.000001
-rw-r--r-- 1 root root 143 Mar  8 04:00 mysql-bin.000002

1.7 mysql 中间件 Atlas

1.7.1 atlas 简介

  Atlas 是由 Qihoo 360 公司 Web 平台部基础架构团队开发维护的一个基于 MySQL 协议的数据中间层项目。它在 MySQL 官方推出的 MySQL-Proxy 0.8.2 版本的基础上,修改了大量 bug,添加了很多功能特性。目前该项目在 360 公司内部得到了广泛应用,很多 MySQL 业务已经接入了 Atlas 平台,每天承载的读写请求数达几十亿条。

  同时,有超过 50 家公司在生产环境中部署了 Atlas,超过 800 人已加入了我们的开发者交流群,并且这些数字还在不断增加。而且安装方便。配置的注释写的蛮详细的,都是中文。

1.7.2 主要功能

  读写分离、从库负载均衡、自动分表、IP 过滤

  SQL 语句黑白名单、DBA 可平滑上下线 DB、自动摘除宕机的 DB

Atlas相对于官方 MySQL-Proxy的优势

1.将主流程中所有 Lua 代码用 C 重写,Lua 仅用于管理接口

2.重写网络模型、线程模型

3.实现了真正意义上的连接池

 

4.优化了锁机制,性能提高数十倍 

1.7.3 使用场景

  Atlas 是一个位于前端应用与后端 MySQL 数据库之间的中间件,它使得应用程序员无需再关心读写分离、分表等与 MySQL 相关的细节,可以专注于编写业务逻辑,同时使得 DBA 的运维工作对前端应用透明,上下线 DB 前端应用无感知。

 

  Atlas 是一个位于应用程序与 MySQL 之间中间件。在后端 DB 看来,Atlas 相当于连接它的客户端,在前端应用看来,Atlas 相当于一个 DB。

  Atlas 作为服务端与应用程序通讯,它实现了 MySQL 的客户端和服务端协议,同时作为客户端与 MySQL 通讯。它对应用程序屏蔽了 DB 的细节,同时为了降低 MySQL 负担,它还维护了连接池.

1.7.4 企业读写分离及分库分表其他方案介绍

    Mysql-proxy(oracle)

    Mysql-router(oracle)

    Atlas (Qihoo 360)

    Atlas-sharding (Qihoo 360)

    Cobar(是阿里巴巴(B2B)部门开发)

    Mycat(基于阿里开源的 Cobar 产品而研发)

    TDDL Smart Client 的方式(淘宝)

    Oceanus(58 同城数据库中间件)

    OneProxy(原支付宝首席架构师楼方鑫开发 )

    vitess(谷歌开发的数据库中间件)

    Heisenberg(百度)

    TSharding(蘑菇街白辉)

    Xx-dbproxy(金山的 Kingshard、当当网的 sharding-jdbc )

    amoeba

1.7.5 安装 Atlas

  软件获取地址: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 (普通) : Atlas-2.2.1.el6.x86_64.rpm

  Atlas (分表) : Atlas-sharding_1.0.1-el6.x86_64.rpm

 下载安装 atlas

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

         至此安装完成

1.7.6 配置 Atlas 配置文件

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

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

生产密文密码:

[root@db03 bin]# /usr/local/mysql-proxy/bin/encrypt 123
3yb5jEku5h4=
[root@db03 bin]# /usr/local/mysql-proxy/bin/encrypt mha
O2jBXONX098=

编辑配置文件

vim  /usr/local/mysql-proxy/conf/test.cnf
[mysql-proxy]
admin-username = user
admin-password = pwd
proxy-backend-addresses = 10.0.0.55:3306
proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306
pwds = repl:3yb5jEku5h4=,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

View Code Atlas 配置文件说明

1.7.7 启动 Atlas

编写一个 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 #重启

  注意:test 是配置文件的名称

脚本内容:

 1 [root@db03 ~]# cat /etc/init.d/atlasd 
 2 #!/bin/sh
 3 #
 4 # atlas:    Atlas Daemon
 5 #
 6 # chkconfig:    - 90 25
 7 # description:  Atlas Daemon
 8 # user:clsn
 9 # Blog: http://blog.nmtui.com
10 # Source function library.
11 
12 Demo=test
13 
14 start()
15 {
16         echo -n $"Starting atlas: "
17         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo start
18 }
19 stop()
20 {
21         echo -n $"Shutting down atlas: "
22         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo stop
23 }
24 status()
25 {
26         echo  $"Atlas status: "
27         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo status
28 }
29 restart()
30 {
31         echo $"Atlas Restart Info: "
32         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo restart
33 }
34 
35 
36 ATLAS="/usr/local/mysql-proxy/bin/mysql-proxyd"
37 [ -f $ATLAS ] || exit 1
38 # See how we were called.
39 case "$1" in
40         start)
41                 start
42                 ;;
43         stop)
44                 stop
45                 ;;
46         restart)
47                 restart
48                 ;;
49         status)
50                 status
51                 ;;
52         *)
53                 echo $"Usage: $0 {start|stop|restart|status}"
54                 exit 1
55 esac
56 exit 0

View Code Atas 管理脚本

检查端口是否正常

[root@db03 ~]# netstat -lntup|grep mysql-proxy
tcp        0      0 0.0.0.0:33060               0.0.0.0:*                   LISTEN      2125/mysql-proxy    
tcp        0      0 0.0.0.0:2345                0.0.0.0:*                   LISTEN      2125/mysql-proxy

1.7.8 Atlas 管理操作

  登入管理接口

[root@db03 ~]# mysql -uuser -ppwd -h127.0.0.1 -P2345

  查看帮助信息

mysql> SELECT * FROM help;

  查看后端的代理库

mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.52:3306 | up    | ro   |
|           3 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

  平滑摘除 mysql

mysql>  REMOVE BACKEND 2;
Empty set (0.00 sec)

   检查是否摘除

mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
2 rows in set (0.00 sec)

  保存到配置文件中

mysql> SAVE CONFIG;

  将节点再添加回来

mysql> add slave 10.0.0.52:3306;
Empty set (0.00 sec)

  查看是否添加成功

mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
|           3 | 10.0.0.52:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

 保存到配置文件中

mysql> SAVE CONFIG;

1.7.9 连接数据库查看负载

通过 atlas 登陆数据,注意,使用的是数据库上的用户及密码

shell> mysql -umha -pmha -h127.0.0.1 -P33060

第一次查询 server_id

mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 53    |
+---------------+-------+
1 row in set (0.00 sec)

第二次查询 server_id

mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 52    |
+---------------+-------+
1 row in set (0.00 sec)

         通过上面可以看到负载成功

1.7.10 读写分离的说明

  Atlas 会透明的将事务语句和写语句发送至主库执行,读语句发送至从库执行。具体以下语句会在主库执行:

显式事务中的语句

autocommit=0 时的所有语句

含有 select GET_LOCK()的语句

除 SELECT、SET、USE、SHOW、DESC、EXPLAIN 外的。

从库负载均衡配置

proxy-read-only-backend-addresses=ip1:port1@权重,ip2:port2@权重

1.7.11 Atlas 高级功能

自动分表

  使用 Atlas 的分表功能时,首先需要在配置文件 test.cnf 设置 tables 参数。

tables 参数设置格式:数据库名.表名.分表字段.子表数量,比如:

你的数据库名叫 school,表名叫 stu,分表字段叫 id,总共分为 2 张表,那么就写为 school.stu.id.2,如果还有其他的分表,以逗号分隔即可。

用户需要手动建立 2 张子表(stu_0,stu_1,注意子表序号是从 0 开始的)。

所有的子表必须在 DB 的同一个 database 里。

当通过 Atlas 执行(SELECT、DELETE、UPDATE、INSERT、REPLACE)操作时,Atlas 会根据分表结果(id%2=k),定位到相应的子表(stu_k)。

例如,执行 select * from stu where id=3;,Atlas 会自动从 stu_1 这张子表返回查询结果。

但如果执行 SQL 语句(select * from stu;)时不带上 id,则会提示执行 stu 表不存在。

Atles 功能的说明

Atlas 暂不支持自动建表和跨库分表的功能。

Atlas 目前支持分表的语句有 SELECT、DELETE、UPDATE、INSERT、REPLACE。

IP过滤:client-ips

  该参数用来实现 IP 过滤功能。

  在传统的开发模式中,应用程序直接连接 DB,因此 DB 会对部署应用的机器(比如 web 服务器)的 IP 作访问授权。

在引入中间层后,因为连接 DB 的是 Atlas,所以 DB 改为对部署 Atlas 的机器的 IP 作访问授权,如果任意一台客户端都可以连接 Atlas,就会带来潜在的风险。

  client-ips 参数用来控制连接 Atlas 的客户端的 IP,可以是精确 IP,也可以是 IP 段,以逗号分隔写在一行上即可。

  如: clientips=192.168.1.2, 192.168.2 

  这就代表 192.168.1.2 这个 IP 和 192.168.2.*这个段的 IP 可以连接 Atlas,其他 IP 均不能连接。如果该参数不设置,则任意 IP 均可连接 Atlas。如果设置了 client-ips 参数,且 Atlas 前面挂有 LVS,则必须设置 lvs-ips 参数,否则可以不设置 lvs-ips。

SQL语句黑白名单功能: Atlas 会屏蔽不带 where 条件的 delete 和 update 操作,以及 sleep 函数。

1.8 Atlas-Sharding 版本

1.8.1 版本介绍

  Sharding 的基本思想就是把一个数据表中的数据切分成多个部分,  存放到不同的主机上去(切分的策略有多种),  从而缓解单台机器的性能跟容量的问题.

  sharding 是一种水平切分, 适用于单表数据庞大的情景. 目前 atlas 支持静态的

  sharding 方案, 暂时不支持数据的自动迁移以及数据组的动态加入.

  Atlas 以表为单位 sharding, 同一个数据库内可以同时共有 sharding 的表和不 sharding 的表, 不 sharding 的表数据存在未 sharding 的数据库组中.

  目前 Atlas sharding 支持 insert, delete, select, update 语句,  只支持不跨 shard 的事务. 所有的写操作如 insert, delete,  update 只能一次命中一个组, 否则会报”ERROR 1105 (HY000):write operation  is only allow to one dbgroup!”错误.

  由于 sharding 取替了 Atlas 的分表功能, 所以在 Sharding 分支里面,  Atlas 单机分表的功能已经移除, 配置 tables 将不会再有效.

1.8.2 Atlas-Sharding 架构

 

1.8.3 Sharding 配置示例

  Atlas 支持非 sharding 跟 sharding 的表共存在同一个 Atlas 中, 2.2.1 之前的配置可以直接运行. 之前的配置如

proxy-backend-addresses = 192.168.0.12:3306
proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306 ... 

  这配置了一个 master 和两个 slave,这属于非 sharding 的组, 所有非 sharding 的表跟语句都会发往这个组内. 

  所以之前没有 Sharding 的 Atlas 的表可以无缝的在新版上使用,

         注意: 非 Sharding 的组只能配置一个, 而 sharding 的组可以配置多个. 下面的配置, 配置了 Sharding 的组,  注意与上面的配置区分

[shardrule-0]
table = test.sharding_test

  分表名,有数据库+表名组成  t

ype = range

  sharding 类型:range 或 hash

shard-key = id

  sharding 字段

groups = 0:0-999,1:1000-1999

  分片的 group,如果是 range 类型的 sharding,则 groups 的格式是:group_id:id 范围。如果是 hash 类型的 sharding,则 groups 的格式是:group_id。例如 groups = 0, 1

[group-0]
proxy-backend-addresses=192.168.0.15:3306
proxy-read-only-backend-addresses=192.168.0.16:3306
[group-1]
proxy-backend-addresses=192.168.0.17:3306
proxy-read-only-backend-addresses=192.168.0.18:3306

1.8.4 Sharding 限制

关于支持的语句

  Atlas sharding 只对 sql 语句提供有限的支持, 目前支持基本的 Select, insert/replace, delete,update 语句,支持全部的 Where 语法(SQL-92 标准), 不支持 DDL(create drop alter)以及一些管理语句,DDL 请直连 MYSQL 执行, 请只在 Atlas 上执行 Select, insert, delete, update(CRUD)语句.

  对于以下语句, 如果语句命中了多台 dbgroup, Atlas 均未做支持(如果语句只命中了一个 dbgroup, 如  select count(*) from test where id < 1000, 其中 dbgroup0 范围是 0 – 1000,  那么这些特性都是支持的)Limit Offset(支持 Limit)  

Order by

Group by  Join

ON

Count, Max, Min 等函数

增加节点

  注意: 暂时只支持 range 方式的节点扩展, hash 方式由于需要数据迁移, 暂时未做支持.

  扩展节点在保证原来节点的范围不改变的情况下, 如已有 dbgroup0 为范围 0 – 999, dbgroup1 为范围 1000-1999, 这个时候可以增加范围>2000 的节点. 如增加一个节点为 2000 – 2999, 修改配置文件,  重启 Atlas 即可.

1.9 参考文献

 

本文转载自 MHA 高可用架构与 Atlas 读写分离


蜷缩的蜗牛 , 版权所有丨如未注明 , 均为原创丨 转载请注明MHA 高可用架构与 Atlas 读写分离
喜欢 (0)
[]
分享 (0)