Linux 定时备份 MySQL 并推送 Gitee

核心准备工作

环境依赖

确保服务器已安装以下工具:

  • 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 下载备份文件,执行恢复测试,确保备份有效性。

相关推荐
旖旎夜光2 小时前
Linux(7)(下)
linux·学习
吃螺丝粉2 小时前
zookeeper权限设置
linux·运维·服务器
猴子年华、2 小时前
【每日一技】:SQL 常用函数实战速查表(函数 + 场景版)
java·数据库·sql·mysql
月明长歌3 小时前
MySQL数据库约束:把“能插入”升级成“插入就对”
数据库·mysql·oracle
一只旭宝3 小时前
Linux专题十三:shell脚本编程
linux·运维·服务器
·云扬·3 小时前
InnoDB Cluster 常见管理命令
数据库·mysql
筵陌3 小时前
MySQL内置函数
数据库·mysql
小馬佩德罗3 小时前
如何将x264 x265的动态库编译入Linux系统中的FFmpeg源码 - x264库编译
linux·ffmpeg·x264
赵民勇4 小时前
awk用法与技巧详解
linux·shell