MHA高可用架构

第1章 高级架构演变:

1.1 高性能架构:

读写分离--->mysql-proxy;atlas;

在主从服务器前增加负载均衡服务器,sql语句进行判断,以实现读写都可以分配给不同的mysql服务器

分库分表--->Mycat;cobar

1.2 高可用架构:

1.      MMM               已经过时

2.      MHA                目前推荐

3.      MGR ; InnoDB cluster  未来的趋势,建议学习

4.      MySQL NDB cluster   不够完善

第2章 MHA的引入

2.1 failover  故障转移:

主库宕机后,备几点要做的事情:

1.      自动监控到工作节点宕机

2.      如果是一主多从结构,需要选择一个能替代原有节点的新节点,(数据最接近原工作节点)作为工作节点

3.      数据补偿:对比从库和原主库的数据差异,进行数据补偿,S2先补偿到S1

4.      需要将剩余节点指向新主库,构成新的主从关系

5.      S1补偿到和原主库一致

a)        ssh能连接上原主库,直接截取保存主库缺失部分binlog

b)        连接不上的话,我们企业中一般会配置binlog server1:1保存主库binlog

6.      加入vip功能,让应用透明化,即用户无感知服务器的切换

第3章 MHA简介:

3.1 MHA软件介绍:

MHA目前在mysql高可用方面是一个相对成熟的解决方案,由日本DeNA公司开发,是一套优秀的作为mysql高可用环境下故障切换的主从提升的高可用软件,mysql故障切换过程中,MHA能做到在10-30秒之内自动完成数据的故障切换动作,兵器在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用

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

MHA还提供在线主库切换的功能,能够安全的奇幻当前运行的胡库到一个新的主库中,大概0.5-2秒内即可完成

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

3.2 MHA工作原理:

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

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

3.      通过中继日志(relay-log)将数据恢复到其他slave

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

5.      将其他从库slave指向新的master,slave,开启主从复制

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

3.3 MHA高可用架构图:

image.png

1.1 MHA工具介绍:

MHA软件由两部分组成,Manager工具包和Node工具包,主要包括以下:

1.1.1 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

1.1.2 Node包括:

save_binary_1ogs              #保存宕机的masterbinlog

apply_diff_relay_logs         #识别relay log的差异

filter_mysqlbinlog            #防止回滚事件一MHA已不再使用这个工具

purge_relay_logs              #清除中继曰志一不会阻塞SQL线程

1.2 MHA的优点:

1.      自动故障转移

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

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

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

5.      性能优秀,可以工作在半同步和一步复制框架

6.      只要relplication支持的存储引擎MHA都支持

第2章 GTID复制技术说明:

2.1 先决条件:

1.      主库和从库要开启binlog

2.      主库和从库server-id必须不同

3.      要有主从复制用户

2.2 GTID复制技术说明:

1.      GTID简介:

GTID的全称为global transaction identifier 即全局事务标识符,是对于一个已提交事务的编号,并且编号全局唯一

GTID=source_id:transaction_id

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

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

2.      GTID事件结构:

image.png

1.      GTID在二进制日志中的结构:

image.png

1.      查看uuid

[root@db03 ~]# cd /application/mysql/data/

[root@db01 data]# cat auto.cnf

[auto]

server-uuid=804b7523-3ec6-11e8-b6de-000c297af7c2

[root@db01 data]# cat /application/mysql/data/auto.cnf

[auto]

server-uuid=f4a983f8-3c06-11e8-a4f3-000c297af7c2

1.1 GTID复制的特点:

1.      整个复制范围内,事务的GTID是一致的

2.      GTID复制时,是自动读取最后一个relay-log事务信息,获取到GTID,从库就按照整个GTID开始自动往后复制,如果relay-log中没有GTID信息,那么从库会去找主库从第一个开始,全量的二进制日志

3.      如果从库是备份恢复搭建的环境,那么从库会从备份结束时的事务ID往后自动复制

4.      GTID复制不支持事务断点

1.2 msyql GTID复制配置:

1.2.1 主库配置文件:

# 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

1.2.2 从库配置文件:

# 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

1.2.3 配置文件解释:

server-id=x                    # 同一个复制拓扑中的所有服务器的id号必须惟一

binlog-format=RO               # 二进制日志格式,强烈建议为ROW

gtid-mode=on                   # 启用gtid类型,否则就是普通的复制架构

enforce-gtid-consistency=true  # 强制GTID的一致性

log-slave-updates=1            # slave更新是否记入日志

1.2.4 复制用户准备:

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

从节点开启复制:

mysql>start slave;

mysql>show slave status\G

1.3 模拟从库写入的报错:

1.      从库执行:

create database nihao;

2.      主库也执行相同命令:

create database nihao;

3.      主库再次之执行后,sql线程宕掉,无法写入:

           Retrieved_Gtid_Set: 94ba1856-3ed2-11e8-b72d-000c291cc733:1-2

            Executed_Gtid_Set: 6e445062-3ed2-11e8-b72c-000c297af7c2:1-3,

94ba1856-3ed2-11e8-b72d-000c291cc733:1           正常绿色部分应该相同 

解决:

mysql> stop slave;

mysql> set gtid_next='94ba1856-3ed2-11e8-b72d-000c291cc733:6';

mysql> begin;commit;

mysql> set  gtid_next='AUTOMATIC';

mysql> start slave;

跳过出错的gtid

第2章 搭建MHA高可用架构:

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

2.1 环境准备:

本次测试共三台服务器:

db01    10.0.0.51

db02    10.0.0.52

db03    10.0.0.53

 

系统基本环境如下:

[root@db01 ~]# cat /etc/redhat-release

CentOS Linux release 7.2.1511 (Core)

[root@db01 ~]# getenforce

Disabled

[root@db01 ~]# systemctl status firewalld.service

firewalld.service - firewalld - dynamic firewall daemon

   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)

   Active: inactive (dead)

[root@db01 ~]# hostname -I

10.0.0.51 172.16.1.51

2.2 修改配置文件:

1.      主节点配置文件:

[mysqld]

basedir=/application/mysql

datadir=/application/mysql/data

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

skip-name-resolve

2.      db02:

[mysqld]

basedir=/application/mysql

datadir=/application/mysql/data

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

skip-name-resolve

3.      db03:

[mysqld]

basedir=/application/mysql

datadir=/application/mysql/data

server-id=3

binlog-format=ROW

gtid-mode=on

enforce-gtid-consistency=true

log-bin=mysql-bin

log_slave_updates = 1

socket=/tmp/mysql.sock

skip-name-resolve

2.3 为了纯净的环境,重新进行了初始化,便于搭建

rm -rf * /appliaction/mysql/data/*

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql --datadir=/application/mysql/data --user=mysql

/etc/init.d/mysqld start

2.4 主库添加复制用户:

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

2.4.1 两个从库执行:

change master to

master_host='10.0.0.51',

master_user='repl',

master_password='123',

master_auto_position=1;

start slave;

2.5 从库关闭自动清除中继日志

MHA架构中,某些从库的数据恢复依赖于其他从库,所以关闭自动清理relay-log功能

set global relay_log_purge = 0;        关闭自动清除relay-log

set global read_only=1;                开启只读模式

vim /etc/my.cnf

[mysqld]

relay_log_purge = 0

2.6 mha所需软件下载地址:

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

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

2.6.1 安装依赖包:

yum  -y install perl-DBD-MySQL perl-Config-Tiny perl-Params-Validate  perl-CPAN perl-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker

2.7 所有节点安装node软件包:

tar xf mha4mysql-node-0.56.tar.gz

cd mha4mysql-node-0.56

perl Makefile.PL

make && make install

2.8 所有节点创建mha用户,但是开启了主从,只在主节点创建就可以了

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

在从节点检查确认是否已经都存在了

select user,host from mysql.user;

+------+-----------+

| user | host      |

+------+-----------+

| mha  | 10.0.0.%  |

| repl | 10.0.0.%  |

| root | 127.0.0.1 |

| root | ::1       |

|      | db02      |

| root | db02      |

|      | localhost |

| root | localhost |

+------+-----------+

2.9 配置mysqlbinlogmysql命令软连接到/usr/bin,所有节点都要操作:

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

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

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

2.10 部署manager节点,建议部署在从节点:

1.      安装依赖

yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes

2.      安装manager软件

tar xf mha4mysql-manager-0.56.tar.gz
cd mha4mysql-manager-0.56
perl Makefile.PL
make && make install

3.      创建必须目录:

mkdir -p /var/log/mha/app1

mkdir -p /etc/mha

4.      编写mha-manager配置文件

[root@db03 mha4mysql-manager-0.56]# vim /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

2.11 配置互信,每台机器上都要做:

ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1

ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.51

ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.52

ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.53

2.11.1 检测互信:

[root@db01 bin]# ssh 10.0.0.51 date

Fri Apr 13 16:13:26 CST 2018

[root@db01 bin]# ssh 10.0.0.52 date

Fri Apr 13 16:13:28 CST 2018

[root@db01 bin]# ssh 10.0.0.53 date

Fri Apr 13 16:13:26 CST 2018

2.12 MHA启动前检测:

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

Fri Apr 13 16:23:33 2018 - [debug]  Connecting via SSH from root@10.0.0.53(10.0.0.53:22) to root@10.0.0.52(10.0.0.52:22)..

Fri Apr 13 16:23:33 2018 - [debug]   ok.

Fri Apr 13 16:23:34 2018 - [info] All SSH connection tests passed successfully.

2.13 启动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 mha]# ps -ef |grep mha

root       4191   2644 11 16:42 pts/1    00:00:00 perl /usr/local/bin/masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover

查看复制状态:

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

MySQL Replication Health is OK.

查看主节点状态:

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

app1 (pid:5700) is running(0:PING_OK), master:10.0.0.51

停止mha服务:

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

第3章 故障模拟:

3.1 发生故障

1.      停掉master节点:

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

2.      db02已经变为主节点:

mysql> show slave status;

Empty set (0.00 sec)

 

mysql> show master status;

+------------------+----------+--------------+------------------+------------------------------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |

+------------------+----------+--------------+------------------+------------------------------------------+

| mysql-bin.000004 |      440 |              |                  | 6e445062-3ed2-11e8-b72c-000c297af7c2:1-2 |

+------------------+----------+--------------+------------------+------------------------------------------+

3.      MHA Manager节点查看:

MHA 守护进程已经帮我们把主节点切换到db02

Started automated(non-interactive) failover.

Selected 10.0.0.52(10.0.0.52:3306) as a new master.

10.0.0.52(10.0.0.52:3306): OK: Applying all logs succeeded.

10.0.0.53(10.0.0.53:3306): OK: Slave started, replicating from 10.0.0.52(10.0.0.52:3306)

10.0.0.52(10.0.0.52:3306): Resetting slave info succeeded.

Master failover to 10.0.0.52(10.0.0.52:3306) completed successfully.

3.2 故障修复:

1.      修复故障库,并重新启动:

2.      在日志中找出change master to 语句,将修复好的故障库加入主从架构中,作为新主库的从库,MHA将不会切换主库

[root@db03 app1]# cat manager|grep -i 'change master to'

Fri Apr 13 16:49:09 2018 - [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';

3.      登录到修复好的故障库,执行change master to

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

Query OK, 0 rows affected, 2 warnings (0.09 sec)

 

start slave;

4.      修改MHA配置文件,server标签重新添加回去,故障库宕机后,mha会自动把server标签删除

vim /etc/mha/app1.cnf

[server1]
hostname=10.0.0.51
port=3306

5.      重新启动mha服务

第4章 设置故障时根据权重切换:

4.1 修改server的权重:

[server1]

hostname=10.0.0.51

port=3306

candidate_master=1

check_repl_delay=0

4.2 配置说明:

candidate_master=1                  ---->不管怎样都切到优先级高的主机,一般在主机性能差异的时候用          

check_repl_delay=0                  ---->不管优先级高的备选库,数据延时多久都要往那切

说明:

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

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

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

第5章 配置vip漂移:

5.1 ip漂移的两种方式:

1.      keepalived 管理虚拟ip

2.      MHA自带脚本管理

5.2 MHA脚本方式:

cd   /server/tools/mha4mysql-manager-0.56/samples/scripts

cp   master_ip_failover /usr/local/bin

5.3 脚本中添加vip切换功能

vim /usr/local/bin/master_ip_failover

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

5.4 vip功能加入app1.cnf

vi /etc/mha/app1.cnf

master_ip_failover_script=/usr/local/bin/master_ip_failover

5.5 在主节点生成vip:

ifconfig eth0:1 10.0.0.55/24

5.6 重启mha使配置生效:

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

Stopped app1 successfully.

[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 &

5.7 停掉主节点mysql服务:

/etc/init.d/mysqld stop

5.8 查看vip是否漂移:

[root@db02 data]# ifconfig eth0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

        inet 10.0.0.52  netmask 255.255.255.0  broadcast 10.0.0.255

第6章 binlog server配置:

6.1 部署binlog server

1.      准备一台新的mysql实例,必须开启GTID

2.      停止MHA

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

3.      建立binlog接受目录

mkdir /data/mysql/binlog/

chown -R mysql.mysql /data/

4.      APP1.cnf配置文件中开启binlog server功能

[binlog1]
no_master=1
hostname=10.0.0.53                          ------>db03那台机器
master_binlog_dir=/data/mysql/binlog/                  ------>我们自定义的binlog保存目录

5.      开启binlog接受(接受主库的binlog)

cd  /data/mysql/binlog/
mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &

6.      开启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 &  

6.2 测试binlog备份:

[root@db03 ~]# cd /data/mysql/binlog/

[root@db03 binlog]# ll

total 1236

-rw-rw---- 1 root root     174 Apr 13 14:37 mysql-bin.000001

-rw-rw---- 1 root root     174 Apr 13 14:37 mysql-bin.000002

-rw-rw---- 1 root root   63834 Apr 13 14:37 mysql-bin.000003

-rw-rw---- 1 root root 1190629 Apr 13 14:37 mysql-bin.000004

-rw-rw---- 1 root root       0 Apr 13 14:37 mysql-bin.000005

登录主库刷新日志:

mysql> flush logs;

[root@db03 binlog]# ll

total 1240

-rw-rw---- 1 root root     174 Apr 13 14:37 mysql-bin.000001

-rw-rw---- 1 root root     174 Apr 13 14:37 mysql-bin.000002

-rw-rw---- 1 root root   63834 Apr 13 14:37 mysql-bin.000003

-rw-rw---- 1 root root 1190629 Apr 13 14:37 mysql-bin.000004

-rw-rw---- 1 root root     478 Apr 13 14:40 mysql-bin.000005

-rw-rw---- 1 root root       0 Apr 13 14:40 mysql-bin.000006