MySQL高可用部署

目录

[一、 MHA(一主多从)](#一、 MHA(一主多从))

1.环境准备(所有节点)

[2. 部署 MySQL 主从复制(Master+Slave)](#2. 部署 MySQL 主从复制(Master+Slave))

[3.部署 MHA Manager(管理节点)](#3.部署 MHA Manager(管理节点))

[(1)安装 MHA Manager](#(1)安装 MHA Manager)

[(2)配置 SSH 无密码登录](#(2)配置 SSH 无密码登录)

[(3)创建 MHA 配置文件](#(3)创建 MHA 配置文件)

[4.部署 MHA Node(所有 MySQL 节点)](#4.部署 MHA Node(所有 MySQL 节点))

[5.配置 VIP 切换脚本](#5.配置 VIP 切换脚本)

[5.验证和启动 MHA](#5.验证和启动 MHA)

二、PXC(多主模式)

1.环境准备

[2.安装 PXC 相关软件(所有节点)](#2.安装 PXC 相关软件(所有节点))

3.配置wsrep.cnf

4.初始化集群

5.验证集群状态

[6. 集群维护命令](#6. 集群维护命令)


在数据库高可用方案中,PXC(Percona XtraDB Cluster) 和 MHA(Master High Availability) 是针对 MySQL(及兼容数据库)的两种主流方案,PXC 的核心是 "集群自愈",通过同步复制和节点间通信实现故障检测与自动恢复。MHA 是主从架构的 "故障切换工具",本身不改变主从复制逻辑(异步 / 半同步),核心作用是主库故障时自动完成从库晋升,减少人工干预时间。

一、 MHA(一主多从)

1.环境准备(所有节点)

bash 复制代码
# 关闭防火墙和 SELinux
systemctl stop firewalld
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0


# 配置主机名和 hosts 文件
# 主库(master)
hostnamectl set-hostname mysql-master
cat >> /etc/hosts << EOF
192.168.10.71 mha-manager
192.168.10.72 mysql-master
192.168.10.73 mysql-slave1
192.168.10.74 mysql-slave2
EOF

# 从库1(slave1)和从库2(slave2)执行相同操作,修改hostnamectl为对应主机名


# 安装依赖包
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager

2. 部署 MySQL 主从复制(Master+Slave)

参照Mysql主从复制部署_mysql replication部署操作-CSDN博客

3.部署 MHA Manager(管理节点)

(1)安装 MHA Manager

bash 复制代码
wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.noarch.rpm
yum install -y mha4mysql-node-0.58-0.el7.noarch.rpm
yum install -y mha4mysql-manager-0.58-0.el7.noarch.rpm

(2)配置 SSH 无密码登录

参考ssh免密登录-CSDN博客

(3)创建 MHA 配置文件

bash 复制代码
mkdir -p /etc/mha/masterha
vi /etc/mha/masterha/app1.cnf

配置内容:

bash 复制代码
[server default]
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
master_binlog_dir=/var/lib/mysql
user=mha_admin  # MHA管理用户
password=admin  # MHA管理用户密码
ping_interval=1  # 检测间隔(秒)
repl_user=yang  # 复制用户
repl_password=admin  # 复制用户密码
ssh_user=root  # SSH用户
secondary_check_script=masterha_secondary_check -s mysql-slave1 -s mysql-slave2    # 双节点检测,名称同下
master_ip_failover_script=/usr/local/bin/master_ip_failover
# report_script=/usr/local/bin/send_report    #邮件告警脚本

[server1]
hostname=mysql-master
candidate_master=1
check_repl_delay=0

[server2]
hostname=mysql-slave1
port=3306
candidate_master=1  # 候选主库
check_repl_delay=0  # 不检查复制延迟

[server3]
hostname=mysql-slave2
no_master=1

4.部署 MHA Node(所有 MySQL 节点)

bash 复制代码
# 1.安装 MHA Node
# 在所有MySQL节点(master、slave1、slave2)执行
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.noarch.rpm
yum install -y mha4mysql-node-0.58-0.el7.noarch.rpm


# 2.创建 MHA 管理用户
# 在所有MySQL节点执行
CREATE USER 'mha_admin'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'mha_admin'@'%';
FLUSH PRIVILEGES;

5.配置 VIP 切换脚本

在 mha-manager 节点上创建 /usr/local/bin/master_ip_failover

vi /usr/local/bin/master_ip_failover

chmod +x /usr/local/bin/master_ip_failover

脚本内容:

bash 复制代码
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
my $vip = '192.168.10.100/24';    #设置Virtual IP
my $gateway = '192.168.10.251';    #网关
my $interface = 'ens192';    #指定VIP所在网卡
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig $interface:$key $vip;/sbin/arping -I $interface -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig $interface:$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,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
# $orig_master_host, $orig_master_ip, $orig_master_port are passed.
# If you manage master ip address at global catalog database,
# invalidate orig_master_ip here.
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" ) {
# all arguments are passed.
# If you manage master ip address at global catalog database,
# activate new_master_ip here.
# You can also grant write access (create user, set read_only=0, etc) here.
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";
`ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`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";
}

注意:

脚本常用命令如下:

bash 复制代码
# 将 VIP 移到新主库
/usr/local/bin/master_ip_failover \
  --command=start \
  --ssh_user=root \
  --orig_master_host=mysql-slave2 \
  --orig_master_ip=192.168.10.74 \
  --orig_master_port=3306 \
  --new_master_host=mysql-master \
  --new_master_ip=192.168.10.72 \
  --new_master_port=3306


# 从原主库移除 VIP
/usr/local/bin/master_ip_failover \
  --command=stop \
  --ssh_user=root \
  --orig_master_host=mysql-slave1 \
  --orig_master_ip=192.168.10.73 \
  --orig_master_port=3306


# 检查 VIP 状态
/usr/local/bin/master_ip_failover \
  --command=status \
  --ssh_user=root \
  --orig_master_host=mysql-master

5.验证和启动 MHA

bash 复制代码
# 检查 SSH 连通性
# 在mha-manager节点执行
masterha_check_ssh --conf=/etc/mha/masterha/app1.cnf

# 检查复制状态
masterha_check_repl --conf=/etc/mha/masterha/app1.cnf

# 启动 MHA Manager
nohup masterha_manager --conf=/etc/mha/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

# 查看 MHA 状态
masterha_check_status --conf=/etc/mha/masterha/app1.cnf

注意事项:

二进制日志保留:主库需保留足够的 binlog(expire-logs-days设置长一些),避免故障转移时从库需要旧 binlog。

VIP 管理:生产环境建议配合 Keepalived 或 LVS 实现 VIP 自动漂移。

监控告警:监控 MHA Manager 日志(/var/log/masterha/app1/manager.log)和 MySQL 复制状态。

参数优化:根据实际情况调整ping_interval(检测频率)和secondary_check_script(双节点检测)。

如果要再次运行MHA,需要先删除日志文件/var/log/masterha/app1/app1.failover.complete,并且已经挂掉节点已从主从结构中移除;MHA的设计至少要一主一从。

二、PXC(多主模式)

1.环境准备

bash 复制代码
# 关闭防火墙和 SELinux
systemctl stop firewalld
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0


# 配置主机名和 hosts 文件
# 节点1
hostnamectl set-hostname pxc-node1
echo "192.168.4.1 pxc-node1" >> /etc/hosts
echo "192.168.4.2 pxc-node2" >> /etc/hosts
echo "192.168.4.3 pxc-node3" >> /etc/hosts

# 节点2和节点3执行相同操作,修改hostnamectl为对应主机名

2.安装 PXC 相关软件(所有节点)

配置yum源

bash 复制代码
#!/bin/bash
mkdir /etc/yum.repos.d/backup
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup
cat > /etc/yum.repos.d/base.repo <<EOF
[base]
name=base
baseurl=https://mirrors.aliyun.com/centos/\$releasever/os/\$basearch/ 
        https://mirrors.huaweicloud.com/centos/\$releasever/os/\$basearch/ 
        https://mirrors.cloud.tencent.com/centos/\$releasever/os/\$basearch/
        https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/os/\$basearch/
        http://mirrors.163.com/centos/\$releasever/os/\$basearch/
        http://mirrors.sohu.com/centos/\$releasever/os/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-\$releasever
[epel]
name=epel
baseurl=https://mirrors.aliyun.com/epel/\$releasever/\$basearch/
        https://mirrors.huaweicloud.com/epel/\$releasever/\$basearch/
        https://mirrors.cloud.tencent.com/epel/\$releasever/\$basearch/
        https://mirrors.tuna.tsinghua.edu.cn/epel/\$releasever/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-\$releasever
[extras]
name=extras
baseurl=https://mirrors.aliyun.com/centos/\$releasever/extras/\$basearch/
        https://mirrors.huaweicloud.com/centos/\$releasever/extras/\$basearch/
        https://mirrors.cloud.tencent.com/centos/\$releasever/extras/\$basearch/
        https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/extras/\$basearch/
        http://mirrors.163.com/centos/\$releasever/extras/\$basearch/
        http://mirrors.sohu.com/centos/\$releasever/extras/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-\$releasever
[updates]
name=updates
baseurl=https://mirrors.aliyun.com/centos/\$releasever/updates/\$basearch/
        https://mirrors.huaweicloud.com/centos/\$releasever/updates/\$basearch/
        https://mirrors.cloud.tencent.com/centos/\$releasever/updates/\$basearch/
        https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/updates/\$basearch/
        http://mirrors.163.com/centos/\$releasever/updates/\$basearch/
        http://mirrors.sohu.com/centos/\$releasever/updates/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-\$releasever
[centosplus]
name=centosplus
baseurl=https://mirrors.aliyun.com/centos/\$releasever/centosplus/\$basearch/
        https://mirrors.huaweicloud.com/centos/\$releasever/centosplus/\$basearch/
        https://mirrors.cloud.tencent.com/centos/\$releasever/centosplus/\$basearch/
        https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/centosplus/\$basearch/
        http://mirrors.163.com/centos/\$releasever/centosplus/\$basearch/
        http://mirrors.sohu.com/centos/\$releasever/centosplus/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-\$releasever
EOF
yum clean all
yum repolist
bash 复制代码
# 安装依赖
yum install -y libev lsof perl-Compress-Raw-Bzip2 perl-Compress-Raw-Zlib perl-DBD-MySQL perl-DBI perl-Digest perl-Digest-MD5 perl-IO-Compress perl-Net-Daemon perl-PlRPC qpress socat openssl openssl-devel

# 安装 XtraBackup
yum install percona-xtrabackup-24 -y

# 安装 Percona XtraDB Cluster
install -y Percona-XtraDB-Cluster-57
或者
wget https://repo.percona.com/yum/percona-release-latest.noarch.rpm
yum install -y percona-release-latest.noarch.rpm
percona-release enable-only pxc-57 release
yum install -y Percona-XtraDB-Cluster-57

3.配置wsrep.cnf

在每个节点创建或修改 /etc/percona-xtradb-cluster.conf.d/wsrep.cnf

pxc1(引导节点):

bash 复制代码
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
 
# PXC 特定配置
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_name="PXC-Cluster"
wsrep_cluster_address="gcomm://192.168.10.72,192.168.10.73,192.168.10.74"
wsrep_node_address="192.168.10.72"
wsrep_node_name="pxc-node1"
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:sstpassword"
 
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0

pxc2 和 pxc3:

bash 复制代码
[mysqld]
# 基本配置同上...

# PXC 特定配置 - 仅修改以下两行
wsrep_node_address="192.168.1.102"  # 或 192.168.1.103
wsrep_node_name="pxc2"  # 或 pxc3
wsrep_cluster_address="gcomm://192.168.1.101,192.168.1.102,192.168.1.103"

4.初始化集群

bash 复制代码
# 步骤 1:引导第一个节点(pxc1)
systemctl start mysql@bootstrap.service

# 步骤 2:创建 SST 用户
grep "temporary password" /var/log/mysqld.log
mysql -u root -p
CREATE USER 'sstuser'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'sstuser'@'%';
FLUSH PRIVILEGES;

# 步骤 3:启动其他节点(pxc2 和 pxc3)
systemctl start mysql

5.验证集群状态

在任意节点执行:

bash 复制代码
SHOW STATUS LIKE 'wsrep_cluster_size';
SHOW STATUS LIKE 'wsrep_connected';
SHOW STATUS LIKE 'wsrep_local_state_comment';

6. 集群维护命令

bash 复制代码
停止集群:
# 按顺序停止节点
systemctl stop mysql  # 在 pxc2 和 pxc3 上
systemctl stop mysql@bootstrap.service  # 在 pxc1 上

启动集群:
# 先启动 pxc1
systemctl start mysql@bootstrap.service

# 再启动 pxc2 和 pxc3
systemctl start mysql

重建集群

bash 复制代码
# 1. 停止所有集群节点
sudo systemctl stop mysql
sudo pkill -9 mysqld

# 2. 删除所有节点上的数据目录内容(除第一个节点外)
sudo rm -rf /var/lib/mysql/*
sudo rm -f /var/run/mysqld/mysqld.pid

# 3. 在第一个节点上初始化新集群
sudo mysqld_safe --wsrep-new-cluster &

# 4. 依次启动其他节点
sudo systemctl start mysql