数据损坏的类型
物理损坏 :磁盘、主机、程序、数据文件
逻辑损坏 :drop ..
高可用解决方案选型依据:全年无故障率
无故障时间 故障时间 解决方案
99.9% 0.1% = 525.6 min KA+双主 :人为干预
99.99% 0.01% = 52.56 min MHA :半自动化
应用场景:比较适合非金融类互联网公司。facebook MHA ,淘宝 TMHA --》polardb。替代产品:ORCH go语言。
99.999% 0.001% = 5.256 min PXC 、 MGR 、MGC
应用场景:金融类业务。
99.9999% 0.0001% = 0.5256 min 自动化、云化、平台化
MHA基础环境实施
GTID复制
参考:主从延时问题的监控及处理建议
MHA 软件结构
manager 组件
masterha_manger 启动MHA
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况,配置信息
masterha_master_monitor 检测master是否宕机
masterha_check_status 检测当前MHA运行状态
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息
node 组件
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
MHA软件安装及配置
程序软连接
ln -s /data/app/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /data/app/mysql/bin/mysql /usr/bin/mysql
各节点进行互信
ssh-keygen
ssh-copy-id
各节点验证
db01:
ssh 10.0.1.121 date
ssh 10.0.1.122 date
ssh 10.0.0.53 date
db02:
ssh 10.0.1.121 date
ssh 10.0.1.122 date
ssh 10.0.0.53 date
db03:
ssh 10.0.1.121 date
ssh 10.0.1.122 date
ssh 10.0.0.53 date
安装软件
# 所有节点安装Node软件依赖包
yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
# Manager软件安装(db03)
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
# 在db01主库中创建mha需要的用户
grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';
Manager配置文件准备(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 # MHA的工作日志设置
manager_workdir=/var/log/mha/app1 # MHA工作目录
master_binlog_dir=/data/binlog # 主库的binlog目录
user=mha # 监控用户
password=mha # 监控密码
ping_interval=2 # 心跳检测的间隔时间
repl_password=123 # 复制用户
repl_user=repl # 复制密码
ssh_user=root # ssh互信的用户
[server1] # 节点信息....
hostname=10.0.1.121
port=3306
[server2]
hostname=10.0.1.122
port=3306
candidate_master=1
[server3]
no_master=1
hostname=10.0.0.53
port=3306
EOF
状态检查(db03) ok
masterha_check_ssh --conf=/etc/mha/app1.cnf
masterha_check_repl --conf=/etc/mha/app1.cnf
开启MHA-manager
开启MHA(db03):
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 &
查看MHA状态
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:4719) is running(0:PING_OK), master:10.0.1.121
MHA工作原理
MHA 是当 master 出现故障,挑选一个 slave 作为新的 master 并构建成新的 主从架构的管理工具。从 master 出现故障到构建成新的主从架构时间是 10-30 秒。在 master 出现故障时可能会出现 slave 同步的数据不一致的现象,此工具 可以自动应用差异的中继日志到其他 slave 上保证数据的一致性。
优点:
(1).可以快速的进行故障切换
(2).自动选择数据同步最全的slave,并把差异日志应用到其他slave上
(3).一个mha manage server可以监控很多master,更改升级配置,不影响线上正在运行的数据库
(4).对原先的体系结构的性能影响很小
(5).适合任何支持主从复制的存储引擎
如图:

# 1. 启动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 &
# 2. 监控
/usr/bin/masterha_master_monitor ,每隔ping_interval秒探测1次,连续4次还没有,说明主库宕机。
# 3. 选新主
3.1 日志量 latest
3.2 备选主 pref
3.3 哪些不被选主 bad
no_master=1
log_bin 二进制日志没开
check_slave_delay,如果从库落后主库100M的日志量(可以关闭)
=============
数组:
alive : 存活
latest :最新
pref :备选
bad :不选
选主判断:
伪代码:
if 情况
=1. 如果pref和bad数组当中slave的个数为0,则选择latest数组当中的第一个slave为master。
db02没有candidate_master,又没有以下bad三种情况,db02恰好是latest。
=2. 循环对比latest数组和perf数组的slave,如果存在相同的slave,并且这个slave不在bad数组当中,该slave会被推选为新的master。
db02 pref , latest ,又不是bad,会被选主。
=3. 循环对比slaves数组pref数组当中的slave,如果有一个slave相同并且不在bad数组当中,该就会成为新的master。
db02 ,不是latest,不是bad,是pref。会被选择。
=4. 循环latest数组,如果又循环到的slave不在bad数组当中,这个slave就会成为master。
也就是说就算添加了candidate_master=1,该slave也不一定会成为主库。
db02 , latest ,不是bad
db03 , pref,不是latest ,不是bad
=5. 从活着的slave当中进行循环,如果循环到的slave不在bad数组当中,那么这个slave就会成为主库。
db02 ,slaves ,不是bad 。
else 如果进行了多次选择都找不到主库,那么主库选择失败,failover失败。
==============
4. 数据补偿 :
4.1 原主库ssh能连接
各个从节点调用:save_binary_logs 脚本,立即保存缺失部分的binlog到各自节点/var/tmp目录。
4.2 原主库ssh不能连接
从节点调用apply_diff_relay_logs ,进行relay-log日志差异补偿。
4.3. 额外数据补偿(主库日志冗余机制)
binlog_server.
5. 切换
所有从库解除主从身份。stop slave ; reset slave;
重构新的主从关系。change master to
6. 应用透明(vip)
7. 故障提醒
8. 额外数据补偿
9. 剔除故障节点
10. manager 程序"自杀"
应用透明(VIP)
vip 介绍
#作用网卡:
eth0:1
eth0:1
# IP
vip : 10.0.1.125/24
一定是一个空闲地址。
一定要和对外提供服务的地址同一网段。
不能跨网段。
类似nginx中keepalived的
vip 故障转移脚本
上传脚本文件到/usr/local/bin
[root@db03 mha_script]# \cp -a * /usr/local/bin
修改权限
[root@db03 bin]# chmod +x /usr/local/bin/*
修改内容
[root@db03 bin]#vim /usr/local/bin/master_ip_failover
my $vip = '10.0.1.125/24';
my $key = '1';
my $if = 'eth0';
my $ssh_start_vip = "/sbin/ifconfig $if:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig $if:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I $if -c 3 -A 10.0.1.125";
修改Manager 配置文件
vim /etc/mha/app1.cnf
master_ip_failover_script=/usr/local/bin/master_ip_failover
检查 masterha_check_status --conf=/etc/mha/app1.cnf
重启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 &
手工在主库添加VIP
[root@db02 ~]# ifconfig eth0:1 10.0.1.125/24
故障提醒功能
[root@db03 bin]# vim send_report
my $smtp='smtp.qq.com'; # smtp服务器
my $mail_from='xxxx@qq.com'; # 发件箱
my $mail_user='xxxx'; # 用户名 QQ号
my $mail_pass='gemghsvgkeyzcagh'; # 授权码
my $mail_to=['xxxx@qq.com']; # 收件箱
#my $mail_to=['to1@qq.com','to2@qq.com'];
修改配置文件
vim /etc/mha/app1.cnf
# 添加一行:
report_script=/usr/local/bin/send_report
重启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 &
日志补偿的冗余方案--binlog_server
创建必要目录(db03)
mkdir -p /data/binlog_server/
chown -R mysql.mysql /data/*
cd /data/binlog_server/
[root@db03 ~]# mysql -e "show slave status \G"|grep "Master_Log"
mysqlbinlog -R --host=10.0.1.121 --user=mha --password=mha --raw --stop-never mysql-bin.000004 &
注意:
拉取日志的起点,需要按照目前从库的已经获取到的二进制日志点为起点
配置文件设置
vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.1.123
master_binlog_dir=/data/binlog_server/
重启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 &
MHA高可用,故障模拟及恢复演练
db01:
/etc/init.d/mysqld stop
db03:看日志
[root@db03 binlog_server]# tail -f /var/log/mha/app1/manager
MHA的维护操作 - 在线切换功能
只切换角色
masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.0.1.122 --orig_master_is_new_slave --running_updates_limit=10000
注意:
master_ip_online_change_script is not defined. If you do not disable writes on the current master manually, applications keep writing on the current master. Is it ok to proceed? (yes/NO): yes
1. 此种方法切换,要注意将原主库,FTWRL(Flush table with read lock),否则会造成主从不一致。
2. 手工切换vip
3. 重新拉去新主库的binlog
master_ip_online_change_script功能实现
准备切换脚本
vim /usr/local/bin/master_ip_online_change
my $vip = "10.0.1.125/24";
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key $vip down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.1.125";
修改MHA配置文件
vim /etc/mha/app1.cnf
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
停 MHA
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
检查repl
[root@db03 bin]# masterha_check_repl --conf=/etc/mha/app1.cnf
在线切换
masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.0.1.121 --orig_master_is_new_slave --running_updates_limit=10000
重构binlogserver
[root@db03 bin]# ps -ef |grep mysqlbinlog
root 2144 16272 0 17:50 pts/1 00:00:00 mysqlbinlog -R --host=10.0.1.122 --user=mha --password=x x --raw --stop-never mysql-bin.000005
root 2529 16272 0 1:03 pts/1 00:00:00 grep --color=auto mysqlbinlog
[root@db03 bin]# kill -9 2144
[root@db03 bin]# cd /data/binlog_server/
[root@db03 binlog_server]# ll
total 4
-rw-r----- 1 root root 194 Apr 1 17:50 mysql-bin.000005
[root@db03 binlog_server]# rm -rf *
[root@db03 binlog_server]# mysqlbinlog -R --host=10.0.1.121 --user=mha --password=mha --raw --stop-never mysql-bin.000009 &
[1] 2534
启动MHA
[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 &
[root@db03 binlog_server]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:2535) is running(0:PING_OK), master:10.0.1.121
MHA故障通用修复方法
检查三节点是否启动
检查主从关系
1主2从:
[root@db03 binlog_server]# mysql -e "show slave status\G" |grep "Master_Host"
Master_Host: 10.0.1.122
[root@db01 data]# mysql -e "show slave status\G" |grep "Master_Host"
修复1主从:
db01:
change master to
master_host='10.0.1.122',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
[root@db01 data]# mysql -e "show slave status\G" |grep "Master_Host"
Master_Host: 10.0.1.122
检查vip是否在主库