mysql【周一】day19

思维导图
在这里插入图片描述
主从复制
基本介绍
主从复制搭建:
1、两台+ 同版本的mysql实例;server_id 各不相同
2、主库方面:二进制日志;复制用户
3、从库方面:通过备份恢复初始化数据(将主库之前的数据拿到从库中:采用最近的一次全备)

1、你怎么监控复制延时:
1、second behind master 只能查看出秒数
2、查看日志量 (也可以利用pt-heartbeat工具)

2、主从延时的原因有哪些
主库方面
(binlog是否实时写入 sync_binlog=1)(5.6版本以前dump线程串行工作;5.7开启dump gtid 并行工作 根据gtid写入binlog的落盘顺序) (减少大事务 和线上做DDL导致全局锁)

从库方面
(SQL线程 5.6 默认是串行的;5.7 基于逻辑时钟进行并发回放) (大量DDL 导致锁的争用问题)

特殊从库

延时从库:异步同步到从库中
过滤复制:白名单、黑名单 两者只选其一
gtid
半同步:mysql版本过渡的产物(dump 通过tcp ip方式发送给IO线程后就不管了(有ack的确认 但是只是放在IO的缓存中了 没有落地到relaylog 中,所以不能保证从库的数据一定会落盘),不管IO线程是否接受到了)
半同步作用于IO线程处,在主从双节点上安装插件 semi-sync 作用:只有当日志信息从IO缓存中落地到relaylog中才会给主库反馈一个确认的信息

GTID复制:
只要主库生成的gtid号码 会在传输到从库时,一同传输过去,可以根据gtid号码进行确认是否

gtid和传统主从复制的差异

不同点:
1、搭建时的命令:
master_auto_position=1 自动寻找复制起点

分为两种情况:
没有备份: 自动从主库的第一个gtid对应的position号码开始复制
有备份:
mysqldump -A --master-date=2 /tmp/full.sql
SET @GLOBAL.GTID purged=’ :1-10’;

从库会自动从第11个gtid开始复制

enforce-gtid-consistency=true 强制gtid一致性
log_bin=/data/binlog/mysql-bin 开启binlog日志
log-slave-updates=1 从库强制更新binlog日志
gtid-mode =on 开启gtid

功能:主从之间 自动校验gtid一致性:主库binlog 检验于 从库relaylog 和 binlog

MHA的高可用

1、数据损坏的类型
物理损坏:磁盘、主机、程序、实例、数据文件
逻辑损坏: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基础环境实施
准备3节点MySQL 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

各节点进行互信

db01:

rm -rf /root/.ssh 
ssh-keygen
cd /root/.ssh 
mv id_rsa.pub authorized_keys
scp  -r  /root/.ssh  10.0.0.52:/root 
scp  -r  /root/.ssh  10.0.0.53:/root

各节点验证
db01:

ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date

db02:

ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date

db03:

ssh 10.0.0.51 date
ssh 10.0.0.52 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.0.51
port=3306  
                                
[server2]            
hostname=10.0.0.52
port=3306
candidate_master=1


[server3]
no_master=1
hostname=10.0.0.53
port=3306
EOF

状态检查(db03)

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.0.51

MHA工作原理

站在产品经理的角度看高可用应该如何设计?
在这里插入图片描述
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、 监控

自动调用脚本 masterha_check_ssh 每隔ping_interval(2)秒 去执行一次这个脚本,如果连续四次还是没有 说明主库宕机

/usr/bin/masterha_master_monitor ,每隔ping_interval秒探测1次,连续4次还没有,说明主库宕机。

[root@slave2 bin]# mysql   -umha -pmha -h 10.0.0.51 -e "select  user();"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+
| user()        |
+---------------+
| [email protected] |
+---------------+
[root@slave2 bin]#

3、监控到之后 再选择一个主库

日志量 latest

备选主 pref

哪些不被选主 bad
no_master=1
log_bin 二进制日志没开
check_slave_delay,如果从库落后主库100M的日志量(可以关闭)

alive 存活节点数组 52 53
lastest 最接近主库的从库 ****第二优先级
pref candidate_master=1 备选主 *****优先级最高
bad 设定no_master =1 则不参与选主 ***第三优先级
log_bin 日志没有开启 不参与选主
check_slave_delay 如果从库落后主库100M的日志量 则不会参与选主

选主条件:
①latest 日志量
②备选主 pref candidate_master=1

如果多个从库从这 两个选主条件都满足 那么就会按照配置文件的顺序

选主原理:首先他在alived中查找主机清单,然后排除bad,最后根据pref和latest的优先级选主

如果设置了no_master =1 即使已经没有可以切换的从库了 只剩了配置no_master =1 那么也不会切换给这个配置的从库

=============
数组:
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、数据补偿
情景1:原来的主库 ssh能连接
各个从节点调用save_binary_logs脚本 立即保存缺失部分的binary 到各自节点/var/tmp目录中
情景2:原主库ssh不能连接
从从1调用apply_diff_relay_logs 进行relay-log日志差异补偿给从2 但是如果原主 10 从1 8 从2 6
原主库 10的数据以及不能ssh登录 那么只能将从1的 8 中的 6 7 补偿给 从2 与原来的数据相比 仍然缺少 9 10 两个日志

额外数据补偿
binlog_server 主库日志的冗余机制

原主库ssh能连接
各个从节点调用: save_binary_logs 脚本,立即保存缺失部分的binlog到各自节点/var/tmp目录。
原主库ssh不能连接
从节点调用apply_diff_relay_logs ,进行relay-log日志差异补偿。

额外数据补偿(主库日志冗余机制)

binlog_server.

5、切换主从关系
解除所有从库主从身份。stop slave ; restart slalve
重构新的主从关系 change master to

6、vip应用透明
7、故障提醒
8、额外数据补偿
9、剔除故障节点

10、manager 程序自杀

dos2unix /usr/local/bin/* 利用命令将脚本中的一些中文字符识别出来

应用透明(VIP)
vip 介绍
#作用网卡:
eth0:1
ens33:1
#IP

vip :   10.0.0.55/24

一定是一个空闲地址。
一定要和对外提供服务的地址同一网段。
不能跨网段。

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.0.55/24';
my $key = '1';
my $if  = 'ens33';
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.0.55";

解释

my $vip = '10.0.0.55/24'; vip地址
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; 修改网卡名字
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.0.55";vip地址

修改Manager 配置文件

vim /etc/mha/app1.cnf 

master_ip_failover_script=/usr/local/bin/master_ip_failover

重启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 ens33:1 10.0.0.55/24

故障提醒功能
准备脚本

[root@db03 bin]# vim  send_report 
my $smtp='smtp.qq.com';             # smtp服务器
my $mail_from='[email protected]';    # 发件箱
my $mail_user='22654481';           # 用户名 QQ号
my $mail_pass='gemghsvgkeyzcagh';   # 授权码
my $mail_to=['[email protected]'];    # 收件箱

#my $mail_to=['[email protected]','[email protected]'];

我的配置文件

my $smtp='smtp.163.com';
my $mail_from='[email protected]';
my $mail_user='[email protected]';
my $mail_pass='liushiya111';
#my $mail_to=['[email protected]','[email protected]'];
my $mail_to='[email protected]';

修改配置文件

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.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000002 &

注意:
拉取日志的起点,需要按照目前从库的已经获取到的二进制日志点为起点

配置文件设置

vim /etc/mha/app1.cnf 
[binlog1]
no_master=1
hostname=10.0.0.53
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.0.52 --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功能实现

功能: 在线切换时,自动锁原主库,VIP自动切换

准备切换脚本

vim /usr/local/bin/master_ip_online_change

my $vip = "10.0.0.55/24";
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key $vip down";
my $ssh_Bcast_arp= "/sbin/arping -I ens33 -c 3 -A 10.0.0.55";

修改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.0.51 --orig_master_is_new_slave --running_updates_limit=10000

重构binlogserver

[root@db03 bin]# ps -ef |grep mysqlbinlog
root      28144  16272  0 17:50 pts/1    00:00:00 mysqlbinlog -R --host=10.0.0.52 --user=mha --password=x x --raw --stop-never mysql-bin.000005
root      28529  16272  0 18:03 pts/1    00:00:00 grep --color=auto mysqlbinlog
[root@db03 bin]# kill -9 28144
[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.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000009 &
[1] 28534

启动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:28535) is running(0:PING_OK), master:10.0.0.51
  1. MHA故障通用修复方法
    9.0 检查三节点是否启动

9.1 检查主从关系
1主2从:

[root@db03 binlog_server]# mysql -e "show slave status\G" |grep "Master_Host"
Master_Host: 10.0.0.52
[root@db01 data]#  mysql -e "show slave status\G" |grep "Master_Host"

修复1主从:
db01:

change master to 
master_host='10.0.0.52',
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.0.52

检查vip是否在主库

[root@db02 data]# ip a

检查binlog_server状态

[root@db03 binlog_server]# ps -ef |grep mysqlbinlog
root      77828  39593  0 17:53 pts/2    00:00:00 grep --color=auto mysqlbinlog
[root@db03 binlog_server]# 

修复binlog_server:

[root@db03 binlog_server]# rm -rf /data/binlog_server/*

[root@db03 binlog_server]# cd /data/binlog_server/
[root@db03 ~]# mysql -e "show slave status \G"|grep "Master_Log"
[root@db03 ~]# mysqlbinlog  -R --host=10.0.0.52 --user=mha --password=mha --raw  --stop-never mysql-bin.000002 &

检查配置文件
三个节点是否存在:

[root@db03 binlog_server]# cat /etc/mha/app1.cnf 

添加新节点到配置文件:

masterha_conf_host --command=add --conf=/etc/mha/app1.cnf --hostname=10.0.0.51 --block=server1 --params="port=3306"

++++++++
masterha_conf_host --command=delete --conf=/etc/mha/app1.cnf --block=server1
++++++++

检查ssh互信和repl

[root@db03 ~]# masterha_check_ssh  --conf=/etc/mha/app1.cnf
[root@db03 ~]# masterha_check_repl  --conf=/etc/mha/app1.cnf 

启动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 ~]# masterha_check_status   --conf=/etc/mha/app1.cnf 
app1 (pid:78201) is running(0:PING_OK), master:10.0.0.52
[root@db03 ~]#
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章