MySQL高可用-MHA

MySQL高可用-MHA

Deng YongJie's blog 734 2022-05-01

第1章 MHA介绍

1.MHA介绍

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案。
它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为 MySQL高可用性
环境下故障切换和主从提升的高可用软件。

在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障
切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

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

2.MHA的优势

1.自动故障转移快
2.主库崩溃不存在数据一致性问题
3.配置不需要对当前mysql环境做重大修改
4.不需要添加额外的服务器(仅一台manager就可管理上百个replication)
5.性能优秀,可工作在半同步复制和异步复制,当监控mysql状态时,仅需要每隔N秒 向master发送ping包(默认3秒),所以对性能无影响。你可以理解为MHA的性能和简 单的主从复制框架性能一样。
6.只要replication支持的存储引擎,MHA都支持,不会局限于innodb

3.MHA功能

1.监控
2.选主
3.应用透明(vip)
4.故障提醒
5.额外数据补偿
6.剔除故障节点
7.manager 程序"自杀"

4.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线程)

第2章 基础主从复制环境搭建部署

0.部署环境说明

三个MySQL节点,GTID,主从复制

1.mysql环境

清除以前的环境:

pkill mysqld
rm -rf /data/

mkdir -p /data/mysql_3306/
mkdir -p /mysql_binlog/
chown -R mysql.mysql /opt/mysql*
chown -R mysql.mysql /data/
chown -R mysql.mysql /mysql_binlog/

cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
datadir=/data/mysql_3306
basedir=/opt/mysql/
socket=/tmp/mysql.sock
port=3306
server_id=51
log_bin=/mysql_binlog/mysql-bin
autocommit=0
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

[mysql]
socket=/tmp/mysql.sock

[client]
socket=/tmp/mysql.sock
EOF

mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --
datadir=/data/mysql_3306/
systemctl stop mysqld
systemctl start mysqld
netstat -lntup|grep 3306
mysqladmin password '123'

操作命令:

mkdir -p /data/mysql_3306/
mkdir -p /mysql_binlog/
yum remove mariadb-libs -y
rm -rf /etc/my.cnf
yum install -y libaio-devel
tar zxf mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz -C /opt/
mv /opt/mysql-5.7.28-linux-glibc2.12-x86_64 /opt/mysql-5.7.28
ln -s /opt/mysql-5.7.28 /opt/mysql
echo 'export PATH=$PATH:/opt/mysql/bin' >>/etc/profile
source /etc/profile
mysql -V
useradd -s /sbin/nologin -M mysql
chown -R mysql.mysql /opt/mysql*
chown -R mysql.mysql /data/
chown -R mysql.mysql /mysql_binlog/

#db-51的配置
cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
datadir=/data/mysql_3306
basedir=/opt/mysql/
socket=/tmp/mysql.sock
port=3306
server_id=51
log_bin=/mysql_binlog/mysql-bin
autocommit=0
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
EOF

#db-52的配置
cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
datadir=/data/mysql_3306
basedir=/opt/mysql/
socket=/tmp/mysql.sock
port=3306
server_id=52
log_bin=/mysql_binlog/mysql-bin
autocommit=0
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
EOF

#db-53的配置
cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
datadir=/data/mysql_3306
basedir=/opt/mysql/
socket=/tmp/mysql.sock
port=3306
server_id=53
log_bin=/mysql_binlog/mysql-bin
autocommit=0
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
EOF
mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --
datadir=/data/mysql_3306/
cp /opt/mysql/support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
systemctl start mysqld
netstat -lntup|grep 3306
mysqladmin password '123'

2.主从复制环境

#db-51创建复制用户
mysql -uroot -p123
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

#db-52和db-53配置复制信息
mysql -uroot -p123
change master to
master_host='10.0.0.51',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
#检查复制状态
show slave status\G

第3章 MHA服务搭建部署

1.创建软连接-所有机器都操作

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

2.节点互信-所有机器都操作

ssh-keygen
ssh-copy-id 10.0.0.51
ssh-copy-id 10.0.0.52
ssh-copy-id 10.0.0.53

3.各节点验证-所有机器都操作

ssh 10.0.0.51 hostname
ssh 10.0.0.52 hostname
ssh 10.0.0.53 hostname

4.所有节点安装node软件

yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

5.db-53 安装Manager软件

yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-ParallelForkManager perl-Time-HiRes
yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

6.db-51 主库中创建mha需要的用户

grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';
select user,host from mysql.user;

7.db-53 准备Manager配置文件

#创建配置文件目录
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
manager_workdir=/var/log/mha/app1
master_binlog_dir=/mysql_binlog/
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
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] # 节点信息....

8.状态检查(db03)

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

9.开启MHA-manager(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 &

10.查看MHA状态

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

第4章 MHA工作原理

1.选主策略

1.日志量最新
2.备选主
3.不被选主

2.故障转移流程

1.从宕机崩溃的master保存二进制日志事件(binlog events);
2.识别含有最新更新的slave;
3.应用差异的中继日志(relay log)到其他的slave;
4.应用从master保存的二进制日志事件(binlog events);
5.提升一个slave为新的master;
6.使其他的slave连接新的master进行复制;

第5章 MHA应用透明

1.vip故障转移脚本

上传脚本文件到/usr/local/bin
\cp -a * /usr/local/bin

2.修改权限

chmod +x /usr/local/bin/*

3.替换字符

dos2unix /usr/local/bin/*

4.修改内容

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";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.0.55";

5.修改配置文件

vim /etc/mha/app1.cnf
master_ip_failover_script=/usr/local/bin/master_ip_failover

6.重启mha

masterha_stop --conf=/etc/mha/app1.cnf 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 &

7.手动在主库添加VIP

ifconfig eth0:1 10.0.0.55/24

第6章 MHA故障提醒

1.准备脚本

vim /usr/local/bin/send_report
my $smtp='smtp.qq.com';
my $mail_from='1043018380@qq.com';
my $mail_user='1043018380';
my $mail_pass='njwygmkbvzlubiji';
my $mail_to='1043018380@qq.com';

2.修改配置文件

vim /etc/mha/app1.cnf
report_script=/usr/local/bin/send_report

3.重启MHA

masterha_stop --conf=/etc/mha/app1.cnf 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 &

第7章 MHA数据补偿

1.创建必要目录(db03)

mkdir -p /data/binlog_server/
chown -R mysql.mysql /data/*
cd /data/binlog_server/

2.拉取最新日志

注意:

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

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.000003 &
ll /data/binlog_server

3.MHA配置文件设置

vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/binlog_server/

4.重启MHA

masterha_stop --conf=/etc/mha/app1.cnf 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 &

第8章 MHA模拟故障演练

1.停掉主库
2.查看VIP是否会漂移
3.查看从库是否升为新的主库
4.查看从库是否切换为新的复制关系

第9章 MHA修复方案

1.确定三个数据库节点都在线

#db-51启动数据库
systemctl start mysqld

2.db-51修复主从复制关系

change master to
master_host='10.0.0.52',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
show slave status\G

3.判断VIP是否存在

#db-52确认是否存在VIP
ip a|grep 10.0.0.55

4.检查binlogserver并修复

ps -ef|grep mysqlbinlog
rm -rf /data/binlog_server/*
cd /data/binlog_server/
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.000003 &

5.检查配置文件确认三个节点是否存在

#添加新节点到配置文件
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

6.检查ssh互信和repl

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

7.启动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 &

8.检查MHA

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

第10章 MHA维护

1.master_ip_online_change_script功能

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

2.准备切换脚本

vim /usr/local/bin/master_ip_online_change
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 $vip down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.0.55";

3.修改MHA配置文件

vim /etc/mha/app1.cnf
master_ip_online_change_script=/usr/local/bin/master_ip_online_change

4.停 MHA

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

5.检查repl

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

6.在线切换

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

7.重构binlogserver

[root@db-53 ~]# ps -ef |grep [m]ysqlbinlog
root 33698 23489 0 21:18 pts/0 00:00:00 mysqlbinlog -R --
host=10.0.0.52 --user=mha --password=x x --raw --stop-never mysql-bin.000003
[root@db-53 ~]# kill 33698
[root@db-53 ~]# cd /data/binlog_server/
[root@db-53 binlog_server]# rm -rf *
[root@db-53 binlog_server]# mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never mysql-bin.000003 &
[1] 36893

8.启动MHA

[root@db-53 ~]# 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] 36915
[root@db-53 ~]# masterha_check_status --conf=/etc/mha/app1.cnf app1 (pid:36915) is running(0:PING_OK), master:10.0.0.51