核心脚本
sh
#!/bin/bash
# ===================== 数据库备份配置区(与你的原配置一致,无需修改!)=====================
DB_USER="root" # MySQL 登录用户名
DB_PWD="123456+" # MySQL 登录密码(含特殊字符,保留原配置)
DB_HOST="127.0.0.1" # MySQL 地址(本地填127.0.0.1)
DB_PORT="3306" # MySQL 端口(默认3306)
BACKUP_DB="MySQL_name" # 要备份的数据库名(全库替换为 --all-databases)
BACKUP_DIR="/data/mysql_backup" # 本地备份目录(无需手动创建,脚本自动建)
KEEP_DAYS=7 # 本地备份保留天数(自动删除7天前文件)
# ===================== SCP远程传输配置区(必须修改!替换为你的远程服务器信息)=====================
REMOTE_USER="root" # 远程服务器登录用户名(如root)
REMOTE_IP="192.168.1.200" # 远程服务器实际IP地址
REMOTE_DIR="/data/mysql_remote_backup" # 远程备份目录(无需手动创建)
REMOTE_SSH_PORT=22 # 远程SSH端口(默认22,修改过则同步更改)
# ==========================================================================================
# 第一步:本地备份目录自动检测+创建(前置核心步骤,失败直接退出)
echo "【$(date +'%Y-%m-%d %H:%M:%S')】开始检测本地备份目录..."
mkdir -p ${BACKUP_DIR} && chmod -R 755 ${BACKUP_DIR}
LOG_FILE="${BACKUP_DIR}/backup_log.log" # 日志文件依赖本地目录,创建后定义
if [ $? -eq 0 ]; then
echo "【$(date +'%Y-%m-%d %H:%M:%S')】本地目录检测/创建成功:${BACKUP_DIR}" >> ${LOG_FILE}
else
echo "【$(date +'%Y-%m-%d %H:%M:%S')】本地目录创建失败!请检查本地磁盘权限/剩余空间" >> ${LOG_FILE}
exit 1 # 本地目录创建失败,终止脚本
fi
# 定义备份文件相关变量
CURRENT_TIME=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${BACKUP_DB}_${CURRENT_TIME}.sql"
COMPRESS_FILE="${BACKUP_FILE}.gz" # 压缩后的备份文件(用于SCP上传)
# 第二步:执行MySQL备份(mysqldump绝对路径,避免命令未找到,错误日志写入文件)
/usr/bin/mysqldump -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PWD} \
--single-transaction --default-character-set=utf8mb4 \
${BACKUP_DB} > ${BACKUP_FILE} 2>> ${LOG_FILE}
# 第三步:检查本地备份是否成功,成功则压缩
if [ $? -eq 0 ] && [ -f ${BACKUP_FILE} ]; then
gzip ${BACKUP_FILE} # 压缩备份文件,节省磁盘/传输带宽
echo "【$(date +'%Y-%m-%d %H:%M:%S')】本地备份成功,已压缩:${COMPRESS_FILE}" >> ${LOG_FILE}
# 第四步:远程备份目录自动检测+创建(SSH免密执行,失败则退出不上传)
echo "【$(date +'%Y-%m-%d %H:%M:%S')】检测远程服务器 ${REMOTE_IP} 备份目录..." >> ${LOG_FILE}
ssh -p ${REMOTE_SSH_PORT} ${REMOTE_USER}@${REMOTE_IP} "mkdir -p ${REMOTE_DIR} && chmod -R 755 ${REMOTE_DIR}" 2>> ${LOG_FILE}
if [ $? -eq 0 ]; then
echo "【$(date +'%Y-%m-%d %H:%M:%S')】远程目录检测/创建成功:${REMOTE_IP}:${REMOTE_DIR}" >> ${LOG_FILE}
else
echo "【$(date +'%Y-%m-%d %H:%M:%S')】远程目录创建失败!请检查免密登录/IP/端口配置" >> ${LOG_FILE}
exit 1 # 远程目录创建失败,终止脚本
fi
# 第五步:SCP上传压缩后的备份文件到远程服务器
echo "【$(date +'%Y-%m-%d %H:%M:%S')】开始上传备份文件到远程服务器..." >> ${LOG_FILE}
scp -P ${REMOTE_SSH_PORT} ${COMPRESS_FILE} ${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/ 2>> ${LOG_FILE}
if [ $? -eq 0 ]; then
echo "【$(date +'%Y-%m-%d %H:%M:%S')】远程上传成功:文件已保存至 ${REMOTE_IP}:${REMOTE_DIR}/" >> ${LOG_FILE}
else
echo "【$(date +'%Y-%m-%d %H:%M:%S')】远程上传失败!请检查网络/远程目录权限" >> ${LOG_FILE}
fi
# 本地备份失败处理
else
echo "【$(date +'%Y-%m-%d %H:%M:%S')】本地备份失败!请检查数据库配置/连接/账号权限" >> ${LOG_FILE}
rm -f ${BACKUP_FILE} 2>/dev/null # 删除空的备份文件,避免占用磁盘
exit 1 # 备份失败,终止脚本
fi
# 第六步:自动清理本地过期备份(保留最近KEEP_DAYS天,删除.sql/.sql.gz)
find ${BACKUP_DIR} -type f \( -name "*.sql" -o -name "*.sql.gz" \) -mtime +${KEEP_DAYS} -delete 2>/dev/null
echo "【$(date +'%Y-%m-%d %H:%M:%S')】本地过期备份清理完成,保留最近${KEEP_DAYS}天文件" >> ${LOG_FILE}
# 日志分隔线,方便区分每次备份记录
echo "----------------------------------------------------------------------------------------" >> ${LOG_FILE}
最后配置 crontab 定时任务
crontab -e
每天凌晨2点执行定时任务
0 2 * * * /bin/bash /data/mysql_backup/mysql_auto_backup.sh >/dev/null 2>&1
CentOS/RHEL 7+ 系统(主流生产环境)
systemctl restart crond
验证服务是否正常运行(显示 active (running) 即为正常)
systemctl status crond