目录
基本概念
工作原理
优势
环境准备:四台centos-其中三台mysql,一台MHA
配置一主两从
安装MHA
配置无密码认证
配置MHA
模拟master故障
基本概念
MySQL 主从复制:是 MySQL 数据库中实现数据冗余、数据备份和高可用性的重要技术手段。它通过将主数据库的 DDL(数据定义语言)和 DML(数据操作语言)操作记录到二进制日志(binlog)中,然后从数据库通过 I/O 线程读取主库的 binlog,并将其应用到自己的数据库中,从而实现主从数据库之间的数据同步。
MHA(Master High Availability):是 MySQL 高可用性解决方案中的一种,主要用于在 MySQL 主从复制架构中,自动检测主数据库的故障,并快速将从数据库提升为新的主数据库,实现故障转移,保证数据库服务的连续性,减少停机时间。
工作原理
MySQL 主从复制原理
- Binlog 日志记录:主库在执行数据变更操作时,会将这些操作记录到二进制日志(Binlog)中,Binlog 记录了所有数据库更改操作的顺序和内容。
- I/O 线程读取:从库启动一个 I/O 线程,该线程与主库建立连接,请求主库发送 Binlog 内容。主库接收到请求后,通过 Dump 线程将 Binlog 内容发送给从库的 I/O 线程。
- Relay Log 中继:从库的 I/O 线程将接收到的 Binlog 内容写入到本地的中继日志(Relay Log)中。
- SQL 线程应用:从库的 SQL 线程读取 Relay Log 中的内容,并按照顺序在从库上执行这些操作,使从库的数据与主库保持一致。
MHA 工作原理
- 节点监控:MHA Manager 节点会定期检查各个 MySQL 节点的状态,包括主库和从库。通过发送心跳包等方式来判断节点是否存活,以及主从复制是否正常运行。
- 故障检测:当 Manager 节点检测到主库出现故障时,会通过一系列的检查和验证来确认主库是否真的不可用,例如检查主库的网络连接、数据库进程状态等。
- 故障转移:在确认主库故障后,MHA 会根据一定的策略从从库中选择一个合适的节点提升为新的主库。这个过程中,MHA 会确保新主库的数据完整性,并协调其他从库连接到新主库,重新建立主从复制关系。
- 数据补偿:在故障转移过程中,如果从库之间的数据存在差异,MHA 会自动进行数据补偿操作,确保新的主从架构下数据的一致性。
优势
- 高可用性:通过 MySQL 主从复制提供数据冗余,MHA 能够在主库出现故障时快速进行故障转移,确保数据库服务的连续性,减少因主库故障导致的业务中断时间。
- 负载均衡:可以将读操作分布到多个从库上,减轻主库的读压力,提高系统的整体性能和并发处理能力,实现读写分离,优化数据库的性能。
- 数据备份与恢复:主从复制本身就是一种实时的数据备份机制,从库可以作为主库数据的实时副本。在需要进行数据恢复时,可以从从库中快速获取数据,而不需要依赖传统的备份恢复方式,提高了数据恢复的效率。
- 扩展性:方便在系统需要扩展时,轻松添加新的从库来满足更多的读请求和数据存储需求,实现系统的横向扩展。
环境准备:四台centos-其中三台mysql,一台MHA
1. 三台mysql都安装mysql,具体的安装步骤可查看
mysql二进制安装https://blog.csdn.net/m0_68472908/article/details/144746891?spm=1001.2014.3001.5502
2. 修改主机名称
hostnamectl set-hostname master && bash
hostnamectl set-hostname slave01 && bash
hostnamectl set-hostname slave02 && bash
3. 全部关闭防火墙
systemctl stop firewalld
setenforce 0
4. 修改master的my.cnf文件
vim /etc/my.cnf
server-id = 1
log_bin = master-bin
log-slave-updates = true
systemctl restart mysqld
5. master:创建软链接
ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
6. slave01,02修改my.cnf文件
#slave01
vim /etc/my.cnf
server-id = 2
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
#slave02
vim /etc/my.cnf
server-id = 3
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
systemctl restart mysqld
7. slave01,02创建软链接
ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
配置一主两从
1. 在三台mysql上都授权两个用户
mysql -uroot -pabc-123
grant replication slave on *.* to 'myslave'@'192.168.180.%' identified by 'abc-123';
grant all privileges on *.* to 'mha'@'192.168.180.%' identified by 'manager';
grant all privileges on *.* to 'mha'@'mysql' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave01' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave02' identified by 'manager';
flush privileges;
2. 在master上查看二进制文件和同步点
select user,host from mysql.user; //查询授权用户
show master status;
3. 在slave01,02上执行同步
change master to master_host='192.168.180.110',master_user='myslave',master_password='abc-123',master_log_file='master-bin.000001',master_log_pos=1748;
start slave;
4. 查看数据同步结果slave01,02
show slave status\G;
5. slave01,02为只读
set global read_only=1;
6. 在master上测试同步,插入数据
create database test_db1;
use test_db1;
create table test1(id int);
insert into test1(id) values(1);
7. 在slave01,02上查询
select * from test_db1.test1;
安装MHA
1. 四台全部下载MHA所需的依赖包
#要使用网络yum源,比如说阿里云,如果网络yum源报错,可以将DNS改成8.8.8.8
yum install -y epel-release //先安装这个
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN lrzsz
2. 四台全部安装mha-node组件
tar zxf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL && make && make install
3. 在MHA服务器上安装manager组件
tar zxf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL && make && make install
配置无密码认证
1. 在mha上配置无密码认证
ssh-keygen -t rsa //全部回车
ssh-copy-id 192.168.180.110 //密码abc-123
ssh-copy-id 192.168.180.120
ssh-copy-id 192.168.180.130
2. 在master上配置无密码认证
ssh-keygen -t rsa //一路回车
ssh-copy-id 192.168.180.120
ssh-copy-id 192.168.180.130
3. 在slave01上配置无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.180.110
ssh-copy-id 192.168.180.130
4. 在slave02上配置无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.180.110
ssh-copy-id 192.168.180.120
配置MHA
1. 在MHA上复制相关脚本到/usr/local/bin目录
ll /root/mha4mysql-manager-0.57/samples/scripts/
cp /root/mha4mysql-manager-0.57/samples/scripts/* /usr/local/bin/
2. 在MHA上替换master_ip_failover内容
echo '' > /usr/local/bin/master_ip_failover
vim /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
use MHA::DBHelper;
my (
$command, $ssh_user, $orig_master_host,
$orig_master_ip, $orig_master_port, $new_master_host,
$new_master_ip, $new_master_port, $new_master_user,
$new_master_password
);
my $vip = '192.168.180.200/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
'new_master_user=s' => \$new_master_user,
'new_master_password=s' => \$new_master_password,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
return 0 unless ($ssh_user);
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
3. 创建MHA软件目录并拷贝配置文件
mkdir /etc/masterha
cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
mkdir -p /var/log/masterha/app1
vim /etc/masterha/app1.cnf
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
user=mha
password=manager
ping_interval=1
remote_workdir=/tmp
repl_user=myslave
repl_password=abc-123
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.180.120 -s 192.168.180.130
shutdown_script=""
ssh_user=root
[server1]
hostname=192.168.180.110
port=3306
[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.180.120
port=3306
[server3]
hostname=192.168.180.130
port=3306
4. 测试无密码认证
masterha_check_ssh -conf=/etc/masterha/app1.cnf
5. 测试mysql主从连接情况
masterha_check_repl -conf=/etc/masterha/app1.cnf
6. 首次配置MHA的VIP地址需要手动进行配置,在master上操作
ifconfig ens33:1 192.168.180.200
ifconfig ens33:1
7. 启动MHA,在mha上
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
#若要关闭:masterha_stop --conf=/etc/masterha/app1.cnf
8. 查看MHA状态
masterha_check_status --conf=/etc/masterha/app1.cnf
9. 查看MHA日志
cat /var/log/masterha/app1/manager.log
模拟master故障
自动切换
1. 手动kill当前的master
pkill -9 mysql
2. 观察MHA日志,是否自动切换成功
tailf /var/log/masterha/app1/manager.log
3. 查看slave01是否接管了VIP,如果接管了就代表切换成功