基于 xtrabackup 完成 MeterSphere 的物理数据备份和还原


朱飞鸽
飞致云 发布于 2023-12-06 / 219 阅读 / 0 评论 /
MeterSphere 使用时间长以后就会积累大量的数据量,使用 mysqldump 命令进行数据库备份缺点也渐渐的显现了出来:锁表、备份时间长是目前最大的痛点,为解决这两个问题,可以使用 xtrabackup 进行物理备份,他的优点有: 备份速度快 物理备份可靠性高 备份过程中,不会打断正在执行的

MeterSphere 使用时间长以后就会积累大量的数据量,使用 mysqldump 命令进行数据库备份缺点也渐渐的显现了出来:锁表、备份时间长是目前最大的痛点,为解决这两个问题,可以使用 xtrabackup 进行物理备份,他的优点有:

  • 备份速度快

  • 物理备份可靠性高

  • 备份过程中,不会打断正在执行的事务(不锁表)

  • 能够基于压缩等功能节约磁盘空间和流量

  • 自动备份校验

  • 还原速度快

  • 可以将备份文件传输到另外一台机器上

  • 在不增加服务器负载的情况下备份数据

一、数据备份

1.1、下载与安装

1.下载 xtrabackup

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.7/binary/tarball/percona-xtrabackup-2.4.7-Linux-x86_64.tar.gz

2.解压 xtrabackup

cd /opt
tar -zxvf percona-xtrabackup-2.4.7-Linux-x86_64.tar.gz

3.测试 xtrabackup

innobackupex --help

有参数输出表示成功!

1.2、备份数据

1.2.1、 全量备份

innobackupex --user=root --password=Password123@mysql --port=3307 --host=10.1.14.116 --datadir=/opt/metersphere/data/mysql --no-timestamp /opt/backup/xfull

上边连接信息+数据库数据文件存放地址,详情可以查看docker-compose-mysql.yml

1.2.2、 增量备份

innobackupex --user=root --password=Password123@mysql --port=3307 --host=10.1.14.116 --datadir=/opt/metersphere/data/mysql  --incremental /opt/backup/xinc --incremental-basedir=/opt/backup/xfull  --parallel=4

上边连接信息+数据库数据文件存放地址,详情可以查看docker-compose-mysql.yml

1.2.3、 验证测试

du -sh /opt/backup/xfull
du -sh /opt/backup/xinc

有数据代表大概率是成功的。

1.3、 备份脚本

#!/bin/bash
MYSQL_DATE_TODAY=$(date +%Y-%m-%d)
MYSQL_DATE_LAST_SUNDAY=$(date -d "${MYSQL_DAY_OF_WEEK} days ago" +%Y-%m-%d)
time=`date "+%Y%m%d_%H%M%S"`
host=`hostname`
#week=0
week=`date +%w`
time_start=`date +%s`
yesterday=`date  +"%Y%m%d" -d  "-1 days"`
n=0             ###设置周几做全备,周日是0,周一到周六依次为1~6
conf_file="/opt/metersphere/conf/my.cnf"
bakuser="root"
bakpass="Password123@mysql"
innobackupex="innobackupex"
bakdir="/opt/backup"
logdir=${bakdir}/log
mysql_port=3307
host_ip=10.1.14.116
datadir="/opt/metersphere/data/mysql"
history_bak_dir=${bakdir}/history
 
function init_dir()
{
    if [ ! -d $bakdir ]
    then
        mkdir -p $bakdir
    fi
    if [ ! -d $logdir ]
    then
        mkdir -p $logdir
    fi
    if [ ! -d $history_bak_dir ]
    then
        mkdir -p $history_bak_dir
    fi
    if [ ! -d ${bakdir}/xinc ]
        then
            mkdir -p ${bakdir}/xinc
        fi
    chown -R root:root  $backdir $logdir $history_bak_dir ${bakdir}/xinc
}
function check_status()
{
    status=`cat ${1}|grep "completed OK"|wc -l`
    if [ $status -eq 2 ]
    then
        ##success backup status
        echo 0 > ${bakdir}/monitor
    else
        ##fail backup status
        echo 1 > ${bakdir}/monitor  
 fi
}
full() {
    ${innobackupex} --defaults-file=${conf_file}  --user=${bakuser} --password=${bakpass} --no-timestamp ${bakdir}/xfull >> ${logdir}/${host}_${time}_full.log 2>&1
    cp ${conf_file} ${bakdir}/xfull
    check_status ${logdir}/${host}_${time}_full.log
}
    
incr() {
    cd ${bakdir}/xinc
    num=`ls -lt| grep ^d |wc -l`
    if [ $num -eq 0 ];then
        last_bak_dir=${bakdir}/xfull
    else
        last_bak_dir=`ls -lt| grep ^d  |awk -F' ' '{print $9}'| head -n 1`
    fi
    echo "bakup_base_dir: " $last_bak_dir >> ${logdir}/${host}_${time}_incr.log 2>&1
    innobackupex --user=${bakuser}  --password=${bakpass} --port=${mysql_port} --host=${host_ip}  --datadir=${datadir} --incremental ${bakdir}/xinc --incremental-basedir=${last_bak_dir}  --parallel=4 >> ${logdir}/${host}_${time}_incr.log 2>&1
    check_status ${logdir}/${host}_${time}_incr.log
}
 
init_dir
if [ $week -eq $n ];then
    if [ -d ${bakdir}/xfull ]; then
            cd ${bakdir}
            tar -czf ${MYSQL_DATE_LAST_SUNDAY}.tar.gz  xfull  xinc log
            mv ${MYSQL_DATE_LAST_SUNDAY}.tar.gz ${history_bak_dir}
            rm -rf ${bakdir}/xfull
            rm -rf ${bakdir}/xinc
            rm -rf ${logdir}
            mkdir ${logdir}
            mkdir ${bakdir}/xinc
    fi
    mkdir ${bakdir}/xfull
    full
else
    incr
fi
time_end=`date +%s`
times=$((${time_end}-${time_start}))
if [ $week -eq $n ]
then
    echo "it takes ${times} seconds to backup the full backup!" >> ${logdir}/${host}_${time}_full.log
else
    echo "it takes ${times} seconds to backup the incr backup!" >> ${logdir}/${host}_${time}_incr.log
fi

1.4、备份策略

备份策略:每天凌晨两点对数据库备份一次,其中,周日为全备,周一到周六都是增量备份,每周轮询一次;然后会打包放入冗余目录下,打包后仍会保留两周。直到下个打包的将其替代。

crontab -e
 
30 3 * * * find /opt/backup/history/  -mtime +14 -type f -exec rm -rf {} \;
30 2 * * * /bin/bash /opt/backup.sh

1.5、手动备份

  1. 删除掉log内的当天文件

  2. 删除掉当天跑的备份文件

  3. 手动运行一下 backup.sh 脚本,重新生成当天备份文件。

二、还原恢复

2.1、传输备份文件

在备份机上,执行以下命令将备份文件传输到待恢复服务器

scp -r  /opt/backup/xfull  root@恢复服务器ip:/data
scp -r  /opt/backup/xinc  root@恢复服务器ip:/data

2.2、停止服务

停止待恢复服务器的服务,主要针对使用 metersphere的./install 安装的 mysql。

msctl stop

2.3、备份当前数据

cp /opt/metersphere/data/mysql /opt/metersphere/data/mysql-bak

2.4、恢复数据

2.4.1、先恢复全量备份

innobackupex --apply-log --redo-only /data/xfull/

2.4.2、再恢复增量备份

合并增量到全备中,恢复增量备份到基础备份的还原上(最后一次增量备份恢复外,其他增量备份恢复要加 --redo-only 参数,此参数表示仅仅只应用 xtrabackup 日志中已提交的事务,不回滚日志中未提交的事务,此命令需要根据 xinc 中文件数量执行多次),最后一次增量备份恢复所需时间相较稍长。

innobackupex --apply-log --redo-only  --incremental-dir=/data/xinc/2022-**/ /data/xfull/    

2.4.3、整体基础备份回滚

对整体的基础备份进行恢复,回滚哪些未提交的数据,前面两个步骤中未提交的事务在这个步骤中才进行回滚。

innobackupex --apply-log /data/xfull

2.4.4、合并完成后整体恢复

innobackupex --copy-back /data/xfull    (此命令完成后会生成新的  /var/lib/mysql/ ,具体位置可以查看这个命令的日志)
chown root:root -R /var/lib/mysql    (更改权限)
mv /var/lib/mysql /opt/metersphere/data/mysql

2.4.5、 启动恢复服务

msctl start

2.5、验证测试

登陆恢复数据的平台,查看用户,日志,权限,接口用例等,与备份服务器一致,表示成功。



是否对你有帮助?