一、方案概述
本方案在原有 MySQL 数据备份架构基础上,通过KVM 虚拟化技术构建 4 台备份虚拟机,替代原单一备份服务器,并利用GlusterFS 分布式文件系统实现项目 server 与备份虚拟机间的目录挂载,确保全量备份文件(tar.bz2 格式)和 binlog 文件的分布式存储与同步,提升备份系统的可靠性、扩展性与数据安全性。
用来练习KVM虚拟化技术与GlusterFS,实现MySQL数据库备份,可用于生产环境不建议照搬
二、前置条件与环境说明
服务器类型 | IP 规划(示例) | 硬件要求 | 预装软件 |
---|---|---|---|
项目 server | 192.168.200.101 | 根据业务需求配置,需预留 /backup 目录存储空间 | MySQL、mysqldump、tar、rsync、GlusterFS 客户端 |
备份物理机(KVM 宿主机) | 192.168.200.102 | CPU 支持虚拟化(开启 VT-x/AMD-V)、内存≥16G、硬盘≥10TB(建议 SSD) | KVM、QEMU、Libvirt、GlusterFS 服务端 |
备份虚拟机(KVM 客户机) | 192.168.200.103~192.168.200.106(4 台) | 每台 2C、4G、500GB 硬盘 | CentOS 7/8、GlusterFS 服务端、rsync |
三、实施方案
步骤一:备份物理机(KVM 宿主机)环境部署
1、开启CPU虚拟化支持
- 重启备份物理机,进入 BIOS 界面(不同主板快捷键不同,常见 F2、Del、F10)。
- 在 “CPU Configuration” 或 “Virtualization Technology” 选项中,启用 “Intel VT-x”(Intel CPU)或 “AMD-V”(AMD CPU),保存并重启。
2、安装KVM及相关工具
# 检查CPU是否支持虚拟化
grep -E 'vmx|svm' /proc/cpuinfo # 输出结果则支持
# 安装KVM及依赖
yum install -y qemu-kvm libvirt virt-install bridge-utils
# 启动并设置开机自启Libvirt服务
systemctl start libvirtd
systemctl enable libvirtd
# 验证KVM安装成功
virsh list --all # 无报错则正常
3、创建4台备份虚拟机(KVM客户机)
-
准备虚拟机镜像文件
#下载 CentOS 7/8 镜像(示例使用 CentOS 7),存储路径为/var/lib/libvirt/images/: wget -P /var/lib/libvirt/images/ http://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
-
批量创建虚拟机(以 1 台为例,其余 3 台修改 IP 和名称)
#使用virt-install命令创建虚拟机,4 台虚拟机名称分别为backup-vm1~backup-vm4,IP 对应 192.168.200.103~106 # 创建backup-vm1(192.168.200.103) virt-install \ --name backup-vm1 \ --ram 4096 \ --vcpus 2 \ --disk path=/var/lib/libvirt/images/backup-vm1.qcow2,size=500,format=qcow2 \ --cdrom /var/lib/libvirt/images/CentOS-7-x86_64-Minimal-2009.iso \ --network bridge=virbr0,model=virtio,ip=192.168.200.103,netmask=255.255.255.0,gateway=192.168.200.1 \ --graphics none \ --os-type linux \ --os-variant rhel7 \ --force # 重复上述命令创建其余3台,修改--name(backup-vm2~4)、--disk path(backup-vm2~4.qcow2)、--network ip(104~106)
- 执行命令后,按提示完成虚拟机的操作系统安装(设置 root 密码、分区等,建议分区时预留
/backup
目录空间)。 - 安装完成后,通过
virsh start backup-vm1
启动虚拟机,virsh autostart backup-vm1
设置开机自启。
- 执行命令后,按提示完成虚拟机的操作系统安装(设置 root 密码、分区等,建议分区时预留
4、配置备份虚拟机网络与SSH免密登录
-
**配置静态 IP:**登录每台备份虚拟机,编辑网卡配置文件(以 CentOS 7 为例),确保 IP 固定
vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 网卡名称可能为ens33,通过ip addr查看 # 修改以下参数 BOOTPROTO=static IPADDR=192.168.200.103 # 对应vm1~4的IP NETMASK=255.255.255.0 GATEWAY=192.168.200.1 DNS1=8.8.8.8 ONBOOT=yes # 重启网络 systemctl restart network
-
SSH 免密登录:从项目 server(192.168.200.101)推送公钥到 4 台备份虚拟机,避免后续操作输入密码
# 在项目server上生成密钥(若已生成可跳过) ssh-keygen -t rsa # 一路回车 # 推送公钥到4台备份虚拟机(以vm1为例,其余3台替换IP) ssh-copy-id root@192.168.200.103 ssh-copy-id root@192.168.200.104 ssh-copy-id root@192.168.200.105 ssh-copy-id root@192.168.200.106
步骤二:创建项目 server 与备份虚拟机的目标目录
1、项目 server 创建目录
# 创建目录并设置权限(mysql用户为数据库运行用户)
mkdir -pv /backup/ruoyi/{Full,binlog}
chown -R mysql:mysql /backup/ruoyi
chmod -R 755 /backup/ruoyi
2、备份虚拟机创建目录
登录每台备份虚拟机(192.168.200.103~106),创建/backup/ruoyi/{binlog,Full}
目录,用于 GlusterFS 挂载
# 4台虚拟机均执行以下命令
mkdir -pv /backup/ruoyi/{binlog,Full}
chown -R mysql:mysql /backup/ruoyi
chmod -R 755 /backup/ruoyi
步骤三:配置 GlusterFS 分布式文件系统
1、安装 GlusterFS 服务端(所有备份虚拟机)
在 4 台备份虚拟机上安装 GlusterFS 服务端:
# 安装EPEL源(CentOS 7需额外安装)
yum install -y epel-release
# 安装GlusterFS服务端
yum install -y glusterfs-server
# 启动并设置开机自启
systemctl start glusterd
systemctl enable glusterd
# 验证服务状态(出现active (running)则正常)
systemctl status glusterd
2、配置 GlusterFS 信任池
选择 1 台备份虚拟机(如 backup-vm1,192.168.200.103)作为主节点,将其他 3 台加入信任池
# 在backup-vm1上执行,添加其他3台虚拟机到信任池
gluster peer probe 192.168.200.104
gluster peer probe 192.168.200.105
gluster peer probe 192.168.200.106
# 查看信任池状态(所有节点状态为Connected则正常)
gluster peer status
3、创建 GlusterFS 分布式卷
分别创建 2 个分布式卷:ruoyi-full-volume
(对应 Full 目录)和ruoyi-binlog-volume
(对应 binlog 目录),使用 4 台虚拟机的/backup/ruoyi/Full
和/backup/ruoyi/binlog
作为存储 brick
# 创建ruoyi-full-volume(用于Full目录)
gluster volume create ruoyi-full-volume \
192.168.200.103:/backup/ruoyi/Full \
192.168.200.104:/backup/ruoyi/Full \
192.168.200.105:/backup/ruoyi/Full \
192.168.200.106:/backup/ruoyi/Full \
force # force用于忽略单节点brick目录非空的警告(若目录为空可省略)
# 创建ruoyi-binlog-volume(用于binlog目录)
gluster volume create ruoyi-binlog-volume \
192.168.200.103:/backup/ruoyi/binlog \
192.168.200.104:/backup/ruoyi/binlog \
192.168.200.105:/backup/ruoyi/binlog \
192.168.200.106:/backup/ruoyi/binlog \
force
# 启动2个分布式卷
gluster volume start ruoyi-full-volume
gluster volume start ruoyi-binlog-volume
# 查看卷状态(Status为Started则正常)
gluster volume info ruoyi-full-volume
gluster volume info ruoyi-binlog-volume
4、项目 server 安装 GlusterFS 客户端并挂载卷
在项目 server(192.168.200.101)上安装客户端,将 GlusterFS 卷挂载到本地/backup/ruoyi/Full
和/backup/ruoyi/binlog
目录
# 安装GlusterFS客户端
yum install -y glusterfs-client
# 卸载本地目录(若之前有数据,先备份再卸载)
umount /backup/ruoyi/Full 2>/dev/null
umount /backup/ruoyi/binlog 2>/dev/null
# 挂载GlusterFS卷到本地目录
mount -t glusterfs 192.168.200.103:/ruoyi-full-volume /backup/ruoyi/Full
mount -t glusterfs 192.168.200.103:/ruoyi-binlog-volume /backup/ruoyi/binlog
# 设置开机自动挂载(编辑/etc/fstab)
echo "192.168.200.103:/ruoyi-full-volume /backup/ruoyi/Full glusterfs defaults,_netdev 0 0" >> /etc/fstab
echo "192.168.200.103:/ruoyi-binlog-volume /backup/ruoyi/binlog glusterfs defaults,_netdev 0 0" >> /etc/fstab
# 验证挂载(出现GlusterFS卷路径则成功)
df -h | grep /backup/ruoyi
步骤四:修改项目 server 备份脚本和定期清理脚本
1、创建全量备份脚本(ruoyi_Full_backup.sh)
vim /root/ruoyi_Full_backup.sh
#!/bin/bash
# 数据库全量备份脚本(GlusterFS版)
# 数据库配置信息
DB_USER="root" # 数据库用户名
DB_PASS="123123" # 数据库密码(根据实际修改)
DB_NAME="ruoyi" # 数据库名
LOCAL_BACKUP_DIR="/backup/ruoyi/Full" # 本地GlusterFS挂载目录(Full)
# 创建备份目录(若GlusterFS挂载正常,目录已存在,此处为容错)
mkdir -p $LOCAL_BACKUP_DIR
# 备份文件名(包含日期,避免重复)
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${DB_NAME}_${DATE}.sql"
TAR_FILE="${LOCAL_BACKUP_DIR}/${DB_NAME}_${DATE}.tar.bz2"
# 使用mysqldump备份数据库
echo "[$DATE] 开始备份数据库: $DB_NAME"
mysqldump -u $DB_USER -p$DB_PASS --databases $DB_NAME > "${LOCAL_BACKUP_DIR}/${BACKUP_FILE}"
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "[$DATE] 数据库备份成功"
# 使用tar压缩为bz2格式(保留原脚本压缩逻辑)
echo "[$DATE] 正在用tar压缩备份文件..."
tar -cjf $TAR_FILE -C $LOCAL_BACKUP_DIR $BACKUP_FILE
# 检查压缩是否成功
if [ $? -eq 0 ]; then
echo "[$DATE] tar打包压缩成功: $TAR_FILE"
# 删除原始sql文件,只保留tar包
rm -f "${LOCAL_BACKUP_DIR}/${BACKUP_FILE}"
else
echo "[$DATE] tar打包压缩失败"
rm -f "${LOCAL_BACKUP_DIR}/${BACKUP_FILE}" # 删除不完整sql文件
fi
else
echo "[$DATE] 数据库备份失败"
rm -f "${LOCAL_BACKUP_DIR}/${BACKUP_FILE}" # 删除不完整备份文件
fi
echo "[$DATE] 全量备份任务完成"
2、创建 binlog 备份脚本(ruoyi_binlog_backup.sh)
原脚本通过 rsync 同步 binlog 到远程服务器,现修改为同步到本地 GlusterFS 挂载目录(/backup/ruoyi/binlog
),无需再监控后发送到远程。
vim /root/ruoyi_binlog_backup.sh
#!/bin/bash
# MySQL binlog备份脚本(GlusterFS版)
# 本地MySQL binlog目录(根据实际路径修改,通过show variables like 'log_bin%'查看)
LOCAL_BINLOG_DIR="/var/lib/mysql"
# 本地GlusterFS挂载目录(binlog)
GLUSTER_BINLOG_DIR="/backup/ruoyi/binlog"
# 确保GlusterFS目录存在
mkdir -p $GLUSTER_BINLOG_DIR
# 监控binlog目录变化(create/modify/move),实时同步到GlusterFS目录
echo "[$(date)] 开始监控binlog目录: $LOCAL_BINLOG_DIR"
inotifywait -m -r -e create,modify,move "$LOCAL_BINLOG_DIR" | while read -r directory events filename; do
# 筛选binlog文件(默认binlog文件名以mysql-bin.开头,根据实际修改)
if [[ $filename == mysql-bin.* ]]; then
echo "[$(date)] 检测到binlog变化: $events $filename,开始同步..."
# 使用rsync同步binlog文件到GlusterFS目录,--delete确保删除已过期的binlog
rsync -avz --delete --include="mysql-bin.*" --exclude="*" "$LOCAL_BINLOG_DIR/" "$GLUSTER_BINLOG_DIR/"
echo "[$(date)] binlog同步完成"
fi
done
3、创建定期清理全量备份脚本(ruoyi_clean_backup.sh)
在项目 server 服务器上创建删除脚本
vim /root/ruoyi_clean_backup.sh
#!/bin/bash
# 全量备份文件清理脚本
# 功能:删除180天前的全量备份文件(.tar.bz2格式)
# 备份目录(GlusterFS挂载的Full目录)
BACKUP_DIR="/backup/ruoyi/Full"
# 日志文件路径
LOG_FILE="/var/log/ruoyi_backup_clean.log"
# 记录当前时间
echo "[$(date +%Y-%m-%d_%H:%M:%S)] 开始执行备份清理任务" >> $LOG_FILE
# 检查备份目录是否存在
if [ ! -d "$BACKUP_DIR" ]; then
echo "[$(date +%Y-%m-%d_%H:%M:%S)] 错误:备份目录 $BACKUP_DIR 不存在" >> $LOG_FILE
exit 1
fi
# 查找并删除180天前的.tar.bz2格式备份文件
echo "[$(date +%Y-%m-%d_%H:%M:%S)] 开始查找180天前的备份文件..." >> $LOG_FILE
find $BACKUP_DIR -name "*.tar.bz2" -type f -mtime +180 -print >> $LOG_FILE
# 执行删除操作
find $BACKUP_DIR -name "*.tar.bz2" -type f -mtime +180 -delete
# 检查删除操作结果
if [ $? -eq 0 ]; then
echo "[$(date +%Y-%m-%d_%H:%M:%S)] 180天前的备份文件已成功删除" >> $LOG_FILE
else
echo "[$(date +%Y-%m-%d_%H:%M:%S)] 错误:删除操作执行失败" >> $LOG_FILE
exit 1
fi
echo "[$(date +%Y-%m-%d_%H:%M:%S)] 备份清理任务执行完成" >> $LOG_FILE
echo "----------------------------------------" >> $LOG_FILE
4、脚本赋权与定时任务配置
-
脚本赋权:确保修改后的脚本有执行权限
chmod +x /root/ruoyi_Full_backup.sh chmod +x /root/ruoyi_binlog_backup.sh chmod +x /root/ruoyi_clean_backup.sh
-
全量备份定时任务:保留原定时任务(凌晨 2 点执行),日志输出路径不变
crontab -e # 确保以下行存在 0 2 * * * /root/ruoyi_Full_backup.sh >> /var/log/ruoyi_backup.log 2>&1 0 3 * * 0 /root/ruoyi_clean_backup.sh
-
binlog 实时同步后台运行:启动 binlog 监控脚本,后台运行并输出日志
# 先停止原脚本(若已运行) ps -ef | grep ruoyi_binlog_backup.sh | grep -v grep | awk '{print $2}' | xargs kill -9 2>/dev/null # 启动新脚本 nohup