目录
[一、 MHA(一主多从)](#一、 MHA(一主多从))
[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)
[2.安装 PXC 相关软件(所有节点)](#2.安装 PXC 相关软件(所有节点))
[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 无密码登录
(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