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高可用架构图:
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 #保存宕机的master的binlog
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事件结构:
1. GTID在二进制日志中的结构:
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 配置mysqlbinlog和mysql命令软连接到/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 [email protected]
ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
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 [email protected](10.0.0.53:22) to [email protected](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
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