上篇文章介绍了基于Xtrabackup重建MySQL备库的流程,相信大家对于Xtrabackup在MySQL备份恢复场景的应用建立了基础认知。本文将会提供一个基于Xtrabackup的MySQL全量备份脚本,该脚本整合了全量备份、目录打包、阿里云OSS上传和本地备份文件清理、钉钉通知等功能,实现了MySQL数据的全量备份和异地转储的功能。
mysql_xtrabackup.sh
#!/bin/bash
set -euo pipefail
START_TIME=$(date +%s)
# 日期和路径变量
DATE=$(date +%F)
BACKUP_DIR="/data/mysqlbackup/fullbackup_$DATE"
ARCHIVE_NAME="mysql_fullbackup_$DATE.tar.gz"
ARCHIVE_PATH="/data/mysqlbackup/$ARCHIVE_NAME"
LOG="/data/mysqlbackup/xtrabackup_$DATE.log"
# Xtrabackup 配置(从环境变量读取,支持默认值)
DATADIR="/data/mysql/mysqldata"
MYSQL_USER="${MYSQL_USER:-backup_user}"
MYSQL_PASS="${MYSQL_PASS:-backup_password}"
# OSS 配置
OSSUTIL="/usr/local/bin/ossutil"
OSS_BUCKET="oss://your_bucket/mysql-backups/"
OSS_ENDPOINT="http://oss-your_region.aliyuncs.com"
# 钉钉机器人 Webhook(替换成你的)
DINGDING_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=your_token"
# 记录日志
log() {
echo"[$(date '+%F %T')] $1" | tee -a "$LOG"
}
# 发送钉钉消息
send_dingding() {
local status="$1"
local msg="$2"
curl -s "$DINGDING_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"msgtype\": \"text\",
\"text\": {
\"content\": \"MySQL 备份通知:$status\n时间:$(date '+%F %T')\n$msg\"
}
}" >/dev/null 2>&1
}
# ========================
# 1. 执行备份
# ========================
if [ -d "$BACKUP_DIR" ]; then
log"检测到备份目录已存在,跳过 xtrabackup 备份阶段"
else
log"=== 开始备份 ==="
if ! xtrabackup --backup \
--target-dir="$BACKUP_DIR" \
--datadir="$DATADIR" \
--user="$MYSQL_USER" \
--compress \
--password="$MYSQL_PASS" >> "$LOG" 2>&1; then
log"备份失败"
send_dingding "备份失败""步骤:xtrabackup --backup\n错误:执行失败"
exit 1
fi
fi
# ========================
# 2. 备份目录打包
# ========================
if [ -f "$ARCHIVE_PATH" ]; then
log"检测到打包文件已存在,跳过打包阶段"
else
log"=== 开始打包 ==="
tar -cf "$ARCHIVE_PATH" -C data/mysqlbackup "$(basename "$BACKUP_DIR")"
log"备份打包完成:$ARCHIVE_PATH"
fi
# 计算包大小
ARCHIVE_SIZE=$(du -sh "$ARCHIVE_PATH" | awk '{print $1}')
# ========================
# 3. 上传到 OSS
# ========================
if ! $OSSUTIL cp "$ARCHIVE_PATH""$OSS_BUCKET" --force --bigfile-threshold 104857600 -j 3 >> "$LOG" 2>&1; then
log"上传 OSS 失败"
send_dingding "备份失败""步骤:上传 OSS\n错误:执行失败\n本地文件已保留:$ARCHIVE_PATH"
exit 1
fi
log"上传至 OSS 成功:$OSS_BUCKET$ARCHIVE_NAME"
# ========================
# 4. 清理本地备份(OSS 成功后)
# ========================
rm -rf "$BACKUP_DIR"
rm -f "$ARCHIVE_PATH"
log"本地备份已清理,仅保留 OSS 版本"
# ========================
# 5. 统计耗时
# ========================
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
HOURS=$((DURATION 3600))
MINUTES=$(((DURATION % 3600) 60))
SECONDS=$((DURATION % 60))
DURATION_FORMAT="${HOURS}h${MINUTES}m${SECONDS}s"
# ========================
# 6. 发送成功通知
# ========================
send_dingding "备份成功""备份文件:$ARCHIVE_NAME\n大小:$ARCHIVE_SIZE\n耗时:$DURATION_FORMAT\n已上传至:$OSS_BUCKET"
log"=== 备份流程完成 ==="
以下内容是对该脚本的解析。
基础设置
1.bash的执行模式
set -euo pipefail
set -euo pipefail
,表示bash脚本的严格模式:
-e
(errexit):遇到非零退出状态(错误)就立即退出脚本。-u
(nounset):引用未定义变量时报错。-o pipefail
:默认情况下,A | B | C 这种管道命令,脚本只会检查最后一个命令的退出码。有了 pipefail,整个管道的退出状态会是 第一个失败命令的退出码。避免命令假成功。
2.定义路径和文件名
DATE=$(date +%F)
BACKUP_DIR="/data/mysqlbackup/fullbackup_$DATE"
ARCHIVE_NAME="mysql_fullbackup_$DATE.tar.gz"
ARCHIVE_PATH="/data/mysqlbackup/$ARCHIVE_NAME"
LOG="/data/mysqlbackup/xtrabackup_$DATE.log"
DATE
:当天日期(格式2025-09-07
)。BACKUP_DIR
:xtrabackup 生成的目录。ARCHIVE_NAME
/ARCHIVE_PATH
:打包后的包路径。LOG
:日志文件路径。
3.MySQL 相关配置
DATADIR="/data/mysql/mysqldata"
MYSQL_USER="${MYSQL_USER:-backup_user}"
MYSQL_PASS="${MYSQL_PASS:-backup_password}"
DATADIR
:MySQL 数据目录。MYSQL_USER
/MYSQL_PASS
:备份账号,支持从环境变量传入,否则用默认值。
4.OSS相关配置
# OSS 配置
OSSUTIL="/usr/local/bin/ossutil"
OSS_BUCKET="oss://your_bucket/mysql-backups/"
OSS_ENDPOINT="http://oss-your_region.aliyuncs.com"
ossutil
:阿里云 OSS 上传工具。OSS_BUCKET
:存储桶路径。OSS_ENDPOINT
:OSS 区域节点。
5.定义Log方法log()
# 记录日志
log() {
echo "[$(date '+%F %T')] $1" | tee -a "$LOG"
}
echo "[$(date '+%F %T')] $1"
: $(date '+%F %T')
:获取当前时间,格式为 YYYY-MM-DD HH:MM:SS
。$1
,函数的第一个参数,也就是你传进去的日志内容,当前时间拼接日志内容形成完整日志,如:[2025-09-07 18:20:30] 开始备份
6.定义发送钉钉消息的方法send_dingding()
# 发送钉钉消息
send_dingding() {
local status="$1"
local msg="$2"
curl -s "$DINGDING_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"msgtype\": \"text\",
\"text\": {
\"content\": \"MySQL 备份通知:$status\n时间:$(date '+%F %T')\n$msg\"
}
}" >/dev/null 2>&1
}
执行备份
if [ -d "$BACKUP_DIR" ]; then
log "检测到备份目录已存在,跳过 xtrabackup 备份阶段"
else
xtrabackup --backup \
--target-dir="$BACKUP_DIR" \
--datadir="$DATADIR" \
--user="$MYSQL_USER" \
--compress \
--password="$MYSQL_PASS"
fi
判断当天目录是否已存在,如果存在就跳过。 否则执行 xtrabackup --backup
:把 MySQL 数据做热备份到$BACKUP_DIR
,并开启压缩。如果失败,会发钉钉通知并退出。
备份文件打包
# ========================
# 2. 备份目录打包(可跳过)
# ========================
if [ -f "$ARCHIVE_PATH" ]; then
log"检测到打包文件已存在,跳过打包阶段"
else
log"=== 开始打包 ==="
tar -cf "$ARCHIVE_PATH" -C data/mysqlbackup "$(basename "$BACKUP_DIR")"
log"备份文件打包完成:$ARCHIVE_PATH"
fi
# 计算包大小
ARCHIVE_SIZE=$(du -sh "$ARCHIVE_PATH" | awk '{print $1}')
上传至OSS
# ========================
# 3. 上传到 OSS
# ========================
if ! $OSSUTIL cp "$ARCHIVE_PATH" "$OSS_BUCKET" --force --bigfile-threshold 104857600 -j 3 >> "$LOG" 2>&1; then
log "上传 OSS 失败"
send_dingding "备份失败" "步骤:上传 OSS\n错误:执行失败\n本地文件已保留:$ARCHIVE_PATH"
exit 1
fi
log "上传至 OSS 成功:$OSS_BUCKET$ARCHIVE_NAME"
! $OSSUTIL cp ...
:执行上传,如果命令返回非 0,则判定上传失败。--force
:强制覆盖 OSS 上同名文件。--bigfile-threshold 104857600
:指定大文件阈值为 100MB(以便 OSSUTIL 使用分片上传)。-j 3
:开启多线程(3 个线程)。>> "$LOG" 2>&1
:将 OSSUTIL 的 stdout/stderr 都写入日志。上传失败时: 写日志 "上传 OSS 失败"通过 send_dingding
发钉钉告警保留本地文件并退出脚本 上传成功时,写日志 "上传至 OSS 成功"
收尾部分
# ========================
# 4. 清理本地备份(OSS 成功后)
# ========================
rm -rf "$BACKUP_DIR"
rm -f "$ARCHIVE_PATH"
log"本地备份已清理,仅保留 OSS 版本"
# ========================
# 5. 统计耗时
# ========================
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
HOURS=$((DURATION 3600))
MINUTES=$(((DURATION % 3600) 60))
SECONDS=$((DURATION % 60))
DURATION_FORMAT="${HOURS}h${MINUTES}m${SECONDS}s"
# ========================
# 6. 发送成功通知
# ========================
send_dingding "备份成功""备份文件:$ARCHIVE_NAME\n大小:$ARCHIVE_SIZE\n耗时:$DURATION_FORMAT\n已上传至:$OSS_BUCKET"
log"=== 备份流程完成 ==="
本地备份文件清理:防止磁盘占用过大 耗时统计:计算备份总耗时 钉钉通知:通过钉钉发送通知,告知备份文件名、大小、耗时和 OSS 位置。
脚本执行
后台执行:
nohup ./mysql_xtrabackup.sh > backup.out 2>&1 &
参考: https://help.aliyun.com/zh/oss/command-line-tools-ossutil-quickstart

点个“赞 or 在看” 你最好看!

👇👇👇 谢谢各位老板啦!!
文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




