【增量备份】使用xtrabackup每天一个增量一周一个全量备份
【增量备份】使用xtrabackup每天一个增量一周一个全量备份
前置知识铺垫
备份类型
- 物理备份
直接对mysql的数据存储目录data进行备份
优点:备份速度和恢复速度快,
缺点:恢复数据对环境和mysql版本有要求,最好保证操作系统环境和mysql版本一致的情况下进行恢复,否则有可能恢复失败 - 逻辑备份
将mysql数据转换成sql语句进行备份
优点:可读性高,大版本一致情况下,在不同操作系统上进行恢复,基本上恢复不会出现问题
缺点:备份速度慢
xtrabackup属于是物理备份,所以备份工作只能在mysql所在的服务器上进行
脚本执行的必要条件
- 电脑上安装了docker(脚本中xtrabackup运行在docker容器中)
- 修改脚本前几行的配置信息
- 保证xtrabackup版本能够兼容mysql的版本,具体可以在xtrabackup官网找到版本对应关系
https://docs.percona.com/percona-xtrabackup/8.0/

配置描述
| 参数 | 示例值 | 说明 |
|---|---|---|
| MYSQL_HOST | 192.168.20.30 | mysql服务的host,不要填127.0.0.1,容器内的127.0.0.1和宿主机ip不一样,最好填写宿主机的局域网ip |
| MYSQL_PORT | 3307 | 宿主机mysql的端口 |
| MYSQL_USER | root | mysql的用户名 |
| MYSQL_PWD | 123456 | mysql的密码 |
| HOST_MYSQL_DATA_DIR | /mysql/data | 宿主机的mysql数据存储目录 |
| HOST_BACKUP_WORK_DIR | /backup/data | 准备一个目录,作为备份的工作目录,备份日志、打包备份的压缩文件等,都会保存在该目录下 |
| XTRABACKUP_VERSION | 8.2 | xtrabackup的版本号 |
| BARK_URL | https://api.day.app/xxxxx | bark的通知服务域名,用于备份失败时,发送通知,具体设置见bark官网,https://bark.day.app/ |
脚本内容
#!/bin/bash
# 配置部分
MYSQL_HOST="192.168.20.30"
MYSQL_PORT="3307"
MYSQL_USER="root"
MYSQL_PWD="12345678"
HOST_MYSQL_DATA_DIR="/Users/macos/Desktop/docker/mysql/data" # 宿主机MySQL 数据目录
HOST_BACKUP_WORK_DIR="/Users/macos/Downloads/backup-test/data" # 宿主机备份的工作目录
XTRABACKUP_VERSION="8.2"
BARK_URL="https://api.day.app/xxxxx" # 使用bark进行备份通知,如果失败了会发送通知
# ==========开始备份==========
DATE=$(date +%Y%m%d%H%M%S) # 当前时间
HOST_FULL_BACKUP_DIR="$HOST_BACKUP_WORK_DIR/full"
HOST_LOG_DIR="$HOST_BACKUP_WORK_DIR/logs"
HOST_TAR_DIR="$HOST_BACKUP_WORK_DIR/tar"
HOST_INC_BASE_DIR="$HOST_BACKUP_WORK_DIR/inc-base-dir" # 用于做增量备份时的基础对比目录[软链接]
# 声明一个名为 print_message 的函数
print_log() {
echo "[$(date +'%F %T')] $1" >> $LOG_FILE
}
main() {
# 每周天做全量备份,那么周天的时候就清除掉旧全量和增量
if [ "$(date +%u)" -eq 7 ]; then
rm -rf $HOST_FULL_BACKUP_DIR
rm -rf $HOST_BACKUP_WORK_DIR/inc
fi
# 创建备份目录
mkdir -p $HOST_LOG_DIR
mkdir -p $HOST_TAR_DIR
chmod -R 755 $HOST_LOG_DIR
# 检查是否有全备份(判定是否存在全量备份目录)
if [ ! -d "$HOST_FULL_BACKUP_DIR" ]; then
LOG_FILE="$HOST_LOG_DIR/backup-$DATE-full.log" # 日志文件
# 如果没有全备份,创建全备份
print_log "开始全量备份"
# 创建保存备份的目录
mkdir -p $HOST_FULL_BACKUP_DIR
chmod -R 755 $HOST_FULL_BACKUP_DIR
# 执行备份,报错不退出
set +e
docker rm pxback-full > /dev/null 2>&1
docker run --name pxback-full -v $HOST_MYSQL_DATA_DIR:/var/lib/mysql -v $HOST_FULL_BACKUP_DIR:/backup:z -it --user root percona/percona-xtrabackup:$XTRABACKUP_VERSION /bin/bash -c "xtrabackup --backup --datadir=/var/lib/mysql --target-dir=/backup --host=$MYSQL_HOST --port=$MYSQL_PORT --user=$MYSQL_USER --password=$MYSQL_PWD --compress" >> $LOG_FILE 2>&1
# 判断备份是否成功
if [ $? -eq 0 ]; then
# 删除容器
docker rm pxback-full > /dev/null 2>&1
set -e
# 创建软链接,用于做增量备份的时候与该备份版本进行增量对比
rm -f $HOST_INC_BASE_DIR
ln -s $HOST_FULL_BACKUP_DIR $HOST_INC_BASE_DIR
# 将备份打包
cd $HOST_FULL_BACKUP_DIR
tar -czvf $HOST_TAR_DIR/$DATE-full.tar.gz * >> $LOG_FILE 2>&1
print_log "全量备份完成"
else
# 删除全量备份的目录,下次再次备份时会重新创建(避免下次备份时进入增量备份)
rm -rf $HOST_FULL_BACKUP_DIR
# 发送错误通知
print_log "error 发送错误通知"
response=$(curl -s -X POST "$BARK_URL" -d "body=全量备份失败(full-$DATE)")
print_log "error 发送错误通知响应: $response"
set -e
print_log "error 全量备份失败"
exit 1
fi
else
LOG_FILE="$HOST_LOG_DIR/backup-$DATE-inc.log" # 日志文件
print_log "开始增量备份"
# 创建本次增量备份的目录
HOST_INC_BACKUP_DIR=$HOST_BACKUP_WORK_DIR/inc/inc-$DATE
mkdir -p $HOST_INC_BACKUP_DIR
chmod -R 755 $HOST_INC_BACKUP_DIR
# 执行备份,报错不退出
set +e
docker rm pxback-inc > /dev/null 2>&1
docker run --name pxback-inc -v $HOST_MYSQL_DATA_DIR:/var/lib/mysql -v $HOST_INC_BASE_DIR:/basedir -v $HOST_INC_BACKUP_DIR:/inc -it --user root percona/percona-xtrabackup:$XTRABACKUP_VERSION /bin/bash -c "xtrabackup --backup --incremental-basedir=/basedir --target-dir=/inc --host=$MYSQL_HOST --port=$MYSQL_PORT --user=$MYSQL_USER --password=$MYSQL_PWD --compress" >> $LOG_FILE 2>&1
# 判断备份是否成功
if [ $? -eq 0 ]; then
# 删除容器
docker rm pxback-inc > /dev/null 2>&1
set -e
# 创建软链接,用于做增量备份的时候与该备份版本进行增量对比
rm -f $HOST_INC_BASE_DIR
ln -s $HOST_INC_BACKUP_DIR $HOST_INC_BASE_DIR
# 将备份打包
cd $HOST_INC_BACKUP_DIR
tar -czvf $HOST_TAR_DIR/$DATE-inc.tar.gz * >> $LOG_FILE 2>&1
print_log "增量备份成功($HOST_INC_BACKUP_DIR)"
else
# 删除备份目录
rm -rf $HOST_INC_BACKUP_DIR
# 发送错误通知
print_log "error 发送错误通知"
response=$(curl -s -X POST "$BARK_URL" -d "body=增量备份失败(inc-$DATE)")
print_log "error 发送错误通知响应: $response"
set -e
print_log "error 增量备份失败($HOST_INC_BACKUP_DIR)"
exit 1
fi
fi
}
main