核心准备工作
环境依赖
确保服务器已安装以下工具:
- Docker
- Git
- mailx(用于邮件通知)
- dos2unix(解决脚本格式问题)
Gitee 配置
创建私有仓库(如 mysql_backup),避免数据泄露。
SSH 免密配置
bash
# 生成 SSH 密钥(一路回车)
ssh-keygen -t rsa -C "your_email@example.com"
# 复制公钥内容
cat ~/.ssh/id_rsa.pub
# Gitee 配置:头像→设置→SSH公钥→粘贴公钥保存
# 测试免密连接
ssh -T git@gitee.com
初始化本地 Git 仓库
bash
mkdir -p /opt/mysql_backup/{backups,gitee_backup}
cd /opt/mysql_backup/gitee_backup
git init
git remote add origin git@gitee.com:your_username/mysql_backup.git
# 配置 Git 用户名和邮箱
git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"
备份脚本优化
创建 /opt/mysql_backup/backup.sh,支持以下功能:
- 指定库或全库备份
- 失败自动重试
- 邮件通知
- 自动压缩和清理旧备份
bash
#!/bin/bash
set -e
# ===== 配置区 =====
CONTAINER_NAME="mysql" # Docker MySQL 容器名
MYSQL_USER="root"
MYSQL_PASSWORD="1234" # MySQL 密码
BACKUP_MODE="all" # 备份模式:all(全库)或指定库名
BACKUP_DIR="/opt/mysql_backup/backups"
GIT_REPO_DIR="/opt/mysql_backup/gitee_backup"
KEEP_BACKUPS=10 # 保留最近10个备份
MAX_RETRIES=3 # 失败重试次数
RETRY_DELAY=60 # 重试间隔(秒)
EMAIL_TO="your_email@example.com" # 通知邮箱
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/mysql_${DATE}.sql"
BACKUP_FILE_GZ="${BACKUP_FILE}.gz"
LOG_FILE="/opt/mysql_backup/backup_${DATE}.log"
# ===== 配置结束 =====
# 日志函数
log() {
echo "[$(date '+%F %T')] $1" | tee -a ${LOG_FILE}
}
# 邮件通知函数
send_email() {
local subject="$1"
local body="$2"
echo -e "${body}" | mailx -s "${subject}" ${EMAIL_TO}
}
# 失败重试函数
retry() {
local n=1
local max=${MAX_RETRIES}
local delay=${RETRY_DELAY}
while true; do
"$@" && break || {
if [[ ${n} -lt ${max} ]]; then
log "失败重试 ${n}/${max},${delay}秒后重试..."
((n++))
sleep ${delay}
else
log "达到最大重试次数 ${max},任务失败"
return 1
fi
}
done
}
# 主备份流程
log "开始 MySQL 备份任务..."
mkdir -p ${BACKUP_DIR}
# 选择备份模式
if [[ "${BACKUP_MODE}" == "all" ]]; then
BACKUP_CMD="mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} --all-databases --single-transaction"
else
BACKUP_CMD="mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${BACKUP_MODE} --single-transaction"
fi
# 执行备份(带重试)
if ! retry docker exec ${CONTAINER_NAME} ${BACKUP_CMD} > ${BACKUP_FILE}; then
log "数据库备份失败!"
send_email "MySQL备份失败" "备份时间:$(date)\n失败日志:${LOG_FILE}"
exit 1
fi
# 压缩备份文件
gzip ${BACKUP_FILE}
log "备份完成:${BACKUP_FILE_GZ}"
# 清理旧备份
ls -tp ${BACKUP_DIR}/*.sql.gz | grep -v '/$' | tail -n +$((KEEP_BACKUPS+1)) | xargs -I {} rm -- {}
log "已清理旧备份,保留最近 ${KEEP_BACKUPS} 个"
# 推送 Gitee(带重试)
if ! retry bash -c "cd ${GIT_REPO_DIR} && cp ${BACKUP_FILE_GZ} . && git add . && git commit -m 'Backup ${DATE}' && git push origin master"; then
log "推送 Gitee 失败!"
send_email "MySQL备份推送失败" "备份成功但推送失败,日志:${LOG_FILE}"
exit 1
fi
log "推送 Gitee 成功!"
send_email "MySQL备份成功" "备份文件:${BACKUP_FILE_GZ}\n备份时间:$(date)"
log "备份任务全部完成!"
脚本修复与权限配置
bash
# 修复 Windows 格式问题
dos2unix /opt/mysql_backup/backup.sh
# 添加执行权限
chmod +x /opt/mysql_backup/backup.sh
# 手动测试脚本
/opt/mysql_backup/backup.sh
定时任务设置
bash
# 编辑 crontab
crontab -e
# 每天 12 点和 0 点备份
0 12 * * * /opt/mysql_backup/backup.sh >> /opt/mysql_backup/backup.log 2>&1
0 0 * * * /opt/mysql_backup/backup.sh >> /opt/mysql_backup/backup.log 2>&1
# 查看定时任务
crontab -l
关键问题排查
备份文件数据量少
检查 BACKUP_MODE 是否设置为 all,确保启用全库备份。
推送 Gitee 报 404
检查 Git 远程地址是否正确:
bash
git remote set-url origin git@gitee.com:your_username/mysql_backup.git
SSH 免密失败
确保私钥权限正确:
bash
chmod 600 ~/.ssh/id_rsa
优化建议
安全优化
使用 ~/.my.cnf 存储 MySQL 凭据,避免明文密码:
ini
[mysqldump]
user=root
password=1234
修改备份命令为:
bash
BACKUP_CMD="mysqldump --defaults-extra-file=/root/.my.cnf --single-transaction ${BACKUP_MODE}"
性能优化
添加 --single-transaction 参数避免锁表,适合 InnoDB 数据库。
验证优化
定期从 Gitee 下载备份文件,执行恢复测试,确保备份有效性。