03-MySQL冗余架构(高可用)

MySQL冗余架构(高可用)

一、MHA高可用架构部署

1. 环境准备

  • 准备3~4台虚拟主机:
    • 1台主库(Master)
    • 2台从库(Slave)本实验使用db03代替为MHA管理节点
    • 1台MHA管理节点(可选)

2. 数据库服务初始化

(1)停止MySQL服务并清理数据目录

[root@db01 ~]# /etc/init.d/mysqld stop
[root@db01 ~]# rm -rf /data/3306/data/*

(2)初始化MySQL数据目录

[root@db01 ~]# /usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql

(3)配置MySQL配置文件(my.cnf

  • 主库配置
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=51
port=3306
autocommit=0
gtid-mode=on
enforce-gtid-consistency=true

[mysql]
prompt=db01 [\\d]>
  • 从库配置
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=52
port=3306
autocommit=0
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

[mysql]
prompt=db02 [\\d]>
  • 从库配置(第二台从库)
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=53
port=3306
autocommit=0
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

[mysql]
prompt=db03 [\\d]>

(4)启动MySQL服务(三台)

[root@db01 ~]# /etc/init.d/mysqld start

3. 主从复制搭建

(1)主库创建复制用户

create user repl@'10.0.0.%' identified with mysql_native_password by '123456';
grant replication slave on *.* to repl@'10.0.0.%';

(2)从库配置主从复制并启动

CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_AUTO_POSITION=1;

START SLAVE;

4. SSH互信配置

(1)清理并生成SSH密钥对

[root@db01 ~]# rm -rf /root/.ssh
[root@db01 ~]# ssh-keygen
[root@db01 ~]# cd /root/.ssh
[root@db01 .ssh]# mv id_rsa.pub authorized_keys

(2)将密钥分发到其他节点

[root@db01 ~]# scp -r /root/.ssh 10.0.0.52:/root
[root@db01 ~]# scp -r /root/.ssh 10.0.0.53:/root
[root@db01 ~]# scp -r /root/.ssh 10.0.0.54:/root  # 如果有MHA管理节点

(3)测试SSH互信

[root@db01 ~]# ssh 10.0.0.51 date
[root@db01 ~]# ssh 10.0.0.52 date
[root@db01 ~]# ssh 10.0.0.53 date
-- 配置节点之间互信,是为了保证数据补偿功能可以应用

5. MHA程序安装与部署

(1)下载并安装MHA程序包

  • 管理程序包(MHA管理节点DB03):

    • 下载链接:mha4mysql-manager
    • 安装命令:
      [root@db03 ~]# yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
      [root@db03 ~]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
      yum localinstall -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
      
  • 节点程序包(MHA管理节点和主从节点DB所有):

    • 下载链接:mha4mysql-node
    • 安装命令:
      [root@db123 ~]# yum install perl-DBD-MySQL -y
      [root@db123 ~]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm 
      yum localinstall -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
      

(2)创建MHA目录和日志目录(db03)

[root@db03 ~]# mkdir -p /etc/mha
[root@db03 ~]# mkdir -p /var/log/mha/app1
#保证MHA服务可以顺利加载mysqlbinlog命令和mysql命令,完成正常高可用切换功能(MHA管理节点)
[root@db03 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
[root@db03 ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql

(3)配置MHA管理节点

  • 在主库(DB01)上创建MHA监控用户:
[root@db01 ~]# mysql
create user mha@'10.0.0.%' identified with mysql_native_password by 'mha';  
grant all privileges on *.* to mha@'10.0.0.%';
-- 创建此用户可以让mha管理节点远程监控主节点和远程管理从节点(主库创建用户)
  • 在管理节点(DB03)上编辑MHA配置文件(/etc/mha/app1.cnf):
[root@db03 ~]# vim /etc/mha/app1.cnf
[server default]
manager_log=/var/log/mha/app1/manager		-- MHA的工作日志设置
manager_workdir=/var/log/mha/app1			-- MHA的工作目录
master_binlog_dir=/data/3306/data			-- 主库的binlog目录
user=mha	--	监控用户,利用此用户连接各个节点,做心跳检测(主要是检测主库的状态)
password=mha  								-- 监控密码
ping_interval=2								-- 心跳检测的间隔时间
repl_password=123456						-- 复制密码				
repl_user=repl	-- 复制用户(用于告知从节点通过新主同步数据信息的用户信息)		
ssh_user=root	-- ssh互信的用户(可以利用互信用户从主库scp获取binlog日志信息,便于从库进行数据信息补偿)

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306
  • 纯净版配置文件
[server default]
manager_log=/var/log/mha/app1/manager         
manager_workdir=/var/log/mha/app1               
master_binlog_dir=/data/3306/data                
user=mha                                                            
password=mha                                  
ping_interval=2                              
repl_password=123456                             
repl_user=repl                                
ssh_user=root   

[server1]                                     
hostname=10.0.0.51
port=3306    

[server2]            
hostname=10.0.0.52
port=3306

#candidate_master=1
[server3]
hostname=10.0.0.53
port=3306

(4)测试MHA配置

# ssh互信检测
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
Thu Mar  6 06:56:36 2025 - [info] All SSH connection tests passed successfully.
# 检测主从状态,启动mha程序前最好进行测试
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

(5)启动MHA服务

[root@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:3861) is running(0:PING_OK), master:10.0.0.51
  • 命令详解

    • masterha_manager:这是 MHA 的核心管理程序,用于监控 MySQL 主从复制的健康状态,并在主库发生故障时自动进行故障切换(failover),确保高可用性。

    • --conf=/etc/mha/app1.cnf:指定 MHA 的配置文件路径。配置文件中包含了主从服务器的连接信息、监控用户、日志路径等关键参数。

    • --remove_dead_master_conf:在故障切换完成后,从配置文件中移除故障主库的信息。这可以避免在后续操作中引用已失效的主库。

    • --ignore_last_failover:忽略上一次故障切换失败的记录。在某些情况下,如果之前的故障切换未成功完成,可能会导致 MHA 无法重新启动。此选项允许 MHA 忽略之前的故障记录并重新启动。

    • < /dev/null > /var/log/mha/app1/manager.log 2>&1 &:将命令的输入重定向到 /dev/null(即忽略输入),并将标准输出和标准错误输出重定向到日志文件 /var/log/mha/app1/manager.log。最后的 & 表示将命令在后台运行,不会阻塞当前终端。

6. MHA高可用服务应用配置(MHA工作原理)

(1)监控主库

  • 启动MHA后会调用masterha_master_monitor脚本进行监控,脚本运行时会使用监控用户连接主库实例;
  • 利用select user();语句向主库发送查询请求;
    • 在MHA管理节点可以获取查询结果,表示主库正常运行
    • 在MHA管理节点无法获取查询结果,表示主库出现异常,后续进行故障转移

(2)选主过程

1.监控节点状态

MHA Manager 会定时检测集群中各个节点的状态,包括主节点和从节点。

2.检测主节点故障

当 MHA Manager 检测到主节点故障时,会触发故障切换过程。

3.选主过程主要依赖以下几个数组:

会扫描配置文件中的节点信息,然后将扫描后节点信息划分到4个数组中,并根据策略选择数组中的节点成为新主

  • alive 数组:用于探测存活的节点状态。(扫描节点是否活着)

  • latest 数组:表示数据量最接近主节点的从节点。(扫描节点延迟情况)

  • pref 数组:扫描节点配置信息(candidate_master=1) 人为定义接替主节点的从节点信息

  • bad 数组:不参与选主 (设置了no_master=1/log_bin=0/数据差异量-100M)

选主的具体规则如下:

  • 如果某个从节点同时满足 alivelatestpref 数组的条件,且不在 bad 数组中,则该节点会被优先选为新主。
  • 如果没有满足上述条件的节点,则会选择 latest 数组中的第一个节点作为新主。
  • 如果所有从节点都不满足条件,则选主失败,故障切换失败。

4个选主策略

1)最优策略 ? (根据节点编号选择 越小越优先)
活着 数据量接近主节点 已经定义接替者身份 不会出现在bad数组中
2)次优策略 (根据节点编号选择 越小越优先)
活着 数据量接近主节点 不会出现在bad数组中
3)再次优策略 (根据节点编号选择 越小越优先)
活着 已经定义接替者身份 不会出现在bad数组中
4)无奈选择 (根据节点编号选择 越小越优先)
活着 不会出现在bad数组中

4.数据同步

选主完成后,MHA 会将其他从节点的数据同步到新的主节点,确保数据一致性。

5.切换完成

MHA 会将所有对主节点的请求重定向到新的主节点,完成故障切换。

6.手动指定新主

如果在配置文件中指定了 candidate_master=1,则该节点会被优先选为新主。

(3)数据补偿

  • 原主库SSH连接正常:各节点自动调用save_binary_logs脚本保存缺失的binlog到/var/tmp/目录。
  • 原主库SSH连接异常:各节点自动调用使用apply_diff_relay_logs脚本补偿relay log差异。
  • 额外数据补偿(利用主库日志冗余机制):MHA提供了binlog_server功能,可以实时拉取主库的binlog日志到备份节点,从而进行数据额外补偿;
实现额外远程binlog备份服务器数据补偿步骤:
#由于本实验没有设置单独的MHA服务器,是在DB03上配置的,所以此配置在DB03上做
#如果有MHA服务器,应在MHA服务器上做

  第一步:运行启动binlog日志同步功能
[root@db03 ~]# mkdir -p /data/mha/app01/
[root@db03 ~]# chown -R mysql.mysql /data/mha/app01/
[root@db03 ~]# cd /data/mha/app01/
[root@db03 app01]# mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never binlog.000001 &
  
  第二步:编写配置文件使MHA支持额外补偿功能
[root@db03 app01]# vim /etc/mha/app1.cnf
[binlog1]
no_master=1								-- 不存于竞选
hostname=10.0.0.53						-- 将日志额外补偿到哪个主机上
master_binlog_dir=/data/mha/app01/		-- 日志额外补偿的存储目录
  第三步:重启MHA服务
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf
[root@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 &
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf

(4)MHA业务切换

  • 其他从库和新主建立主从 -- 重新构建主从

  • MHA管理节点会远程控制 连接所有主和从节点

  • 在新主节点上执行STOP SLAVERESET SLAVE ALL

  • 在其他从节点上,会执行 stop slave /reset slave all/change master to .../start slave

(5)MHA应用透明(实现高可用VIP地址漂移)

  • 在主库(DB01)节点上实现地址创建和地址漂移功能:
[root@db01 ~]# yum install -y net-tools
[root@db01 ~]# ifconfig ens33:1 10.0.0.50/24
  • 编写master_ip_failover脚本实现VIP漂移。
[root@db03 ~]# cd /usr/local/bin/
[root@db03 bin]# master_ip_failover
[root@db03 bin]# yum install -y dos2unix
#将文件从 Windows 风格的换行符 转换为 Unix/Linux 风格的换行符 的一个工具
上传master_ip_failover文件
[root@db03 bin]# dos2unix ./*

[root@db03 bin]# vim master_ip_failover
13 my $vip = '10.0.0.50/24';     -- 定义VIP地址
14 my $key = '1';                -- 定义VIP地址别名编号
15 my $if = 'ens33';             -- 定义VIP地址创建或删除网卡名称
16 my $ssh_start_vip = "/sbin/ifconfig $if:$key $vip";     -- 在新主上创建vip地址
17 my $ssh_stop_vip = "/sbin/ifconfig $if:$key down";      -- 在原主上关闭vip地址
18 my $ssh_Bcast_arp = "/sbin/arping -I ens33 -c 3 -A 10.0.0.50";    -- 修改所有节点mac/arp地址表

[root@db03 bin]# vim /etc/mha/app1.cnf
[server default]
master_ip_failover_script=/usr/local/bin/master_ip_failover
  • 重启MHA服务
重启MHA服务
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf
[root@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 &
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf

(6)报警功能

[root@db03 ~]# cd /usr/local/bin/
上传send_report文件
[root@db03 bin]# dos2unix ./*
[root@db03 bin]# vim send_report
   28 my $smtp='smtp.163.com';                    -- 定义邮件服务域名信息
   29 my $mail_from='dezyan@163.com';          -- 定义自己的邮箱账号
   30 my $mail_user='Dezyan MHA';                 -- 定义自己邮箱用户名
   31 my $mail_pass='GBs4pW73XaqRjrWd';          -- 定义自己邮箱密码(授权码)
   32 my $mail_to='2873390654@qq.com';            -- 定义邮件发送给谁的邮件账号 告知单个DBA人员
      my $mail_to=['to1@qq.com','to2@qq.com'];   -- 定义邮件发送给谁的邮件账号 告知多个DBA人员
      
[root@db03 ~]# vim /etc/mha/app1.cnf
[server default]
report_script=/usr/local/bin/send_repor

[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf
[root@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 &
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf

7. MHA高可用测试

  • 停止主库MySQL服务:
/etc/init.d/mysqld stop
  • 观察VIP地址是否切换、主从是否重构、邮件是否发送、配置文件是否更新、MHA服务是否停止。

三、MHA高可用运维管理

1. 修复MHA架构

(1)处理主库或系统故障

  • 查看错误日志,修复服务或更换硬件。

(2)重新启动MySQL服务

/etc/init.d/mysqld start

(3)重新建立主从关系

CHANGE MASTER TO
MASTER_HOST='10.0.0.52',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_AUTO_POSITION=1;

START SLAVE;

show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0

(4)添加修复配置信息

  • 方式一:编写配置文件
[root@db03 ~]# vim /etc/mha/app1.cnf
[server1]
hostname=10.0.0.51
port=3306
  • 方式二:用脚本添加
[root@db03 ~]# masterha_conf_host --command=add --conf=/etc/mha/app1.cnf --block=server1 --hostname=10.0.0.51  --params="port=3306"
添加新的节点信息
[root@db03 ~]# masterha_conf_host --command=delete --conf=/etc/mha/app1.cnf --block=server1 
删除原有节点信息

(5)恢复binlog远程备份功能

[root@db03 ~]# cd /data/mha/app01/
[root@db03 ~]# rm -f binlog.00000*
[root@db03 ~]# mysqlbinlog -R --host=10.0.0.52 --user=mha --password=mha --raw --stop-never binlog.000001 &

(6)恢复MHA服务

[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
[root@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 &
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf

2. MHA维护性主备切换

  • 步骤一:需要先停止MHA服务
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf    
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
  • 步骤二:编写配置文件信息
VIP漂移功能实现:
方式一: 
masterha_master_monitor -- 监控主库故障 -- 加载配置文件 -- master_ip_failover_script=/usr/local/bin/master_ip_failover
/usr/local/bin/master_ip_failover       利用此脚本实现VIP漂移
方式二: 
masterha_master_switch  -- 加载配置文件 -- master_ip_online_change_script=/usr/local/bin/master_ip_online_change
/usr/local/bin/master_ip_online_change  利用此脚本实现VIP漂移

vim /usr/local/bin/master_ip_online_change
21 my $vip = "10.0.0.50/24";
22 my $key = "1";
23 my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
24 my $ssh_stop_vip = "/sbin/ifconfig ens33:$key $vip down";
25 my $ssh_Bcast_arp= "/sbin/arping -I ens33 -c 3 -A 10.0.0.50";

vim /etc/mha/app1.cnf 
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
  • 步骤三:实现主库切换
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
--conf=/etc/mha/app1.cnf  		-- 获取哪个主从架构需要进行主备切换
--master_state=alive      		-- 指定主节点存活状态进行维护切换
--new_master_host=10.0.0.51     -- 切换后指定新主机节点信息
--orig_master_is_new_slave      -- 主从架构需要重构
--running_updates_limit=10000   -- 切换等待数据补偿超时时间


It is better to execute FLUSH NO_WRITE_TO_BINLOG TABLES on the master before switching. Is it ok to execute on 10.0.0.52(10.0.0.52:3306)? (YES/no):
最好在原有主节点上(10.0.0.52)执行 FLUSH NO_WRITE_TO_BINLOG TABLES 语句命令,可以更好保证主从之间数据一致

FLUSH NO_WRITE_TO_BINLOG TABLES:
1)可以刷新日志binlog日志
2)将此时数据库中表的信息,不要记录到binlog
  • 步骤四:验证
1)关注VIP地址是否切换            	ok
2)关注切换后是否进行了主从重构 	ok
3)关注配置文件信息是否删除       	ok
  • 步骤五:恢复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 &
masterha_check_status --conf=/etc/mha/app1.cnf
posted @ 2025-03-21 16:57  丁志岩  阅读(27)  评论(0)    收藏  举报