数据库备份是运维工作的生命线。作为在Linux环境下管理MySQL多年的老手,我见过太多因为备份不到位导致的数据灾难。今天分享的这套自动化备份方案,是我经过多个生产环境验证的稳定方案,主要解决以下几个核心问题:
这套方案的特点是:
适合中小型MySQL数据库的日常备份需求,单库备份文件通常在几百MB到几十GB范围内都能稳定运行。
首先需要确认MySQL客户端工具路径:
bash复制which mysqldump
典型输出可能是:
code复制/usr/bin/mysqldump
或
code复制/opt/mysql/bin/mysqldump
根据实际路径修改脚本中的mysqldump路径。我建议使用绝对路径而非依赖环境变量,这样在crontab中执行时不会出现命令找不到的问题。
bash复制#!/bin/bash
# 设置字符集避免中文乱码
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# 数据库连接配置
username="db_backup_user" # 建议创建专用备份账号
password="YourStrongPassword"
dbName="your_database_name"
# 保留备份数量
backNumber=30
beginTime=$(date +"%Y年%m月%d日 %H:%M:%S")
# 目录配置
bakDir=/opt/back
logFile=/opt/back/log/bak.log
# 备份文件名
nowDate=$(date +%Y%m%d)
dumpFile="${dbName}_${nowDate}.sql"
gzDumpFile="${dbName}_${nowDate}.tar.gz"
# 创建备份目录
[ ! -d $bakDir ] && mkdir -p $bakDir
cd $bakDir || exit 1
# 执行全量备份
/usr/bin/mysqldump -u${username} -p${password} \
--quick \
--databases ${dbName} \
--single-transaction \
--default-character-set=utf8 \
--set-charset=true \
--result-file=$dumpFile
# 压缩备份文件
/bin/tar -zcvf $gzDumpFile $dumpFile
/bin/rm -f $dumpFile
# 记录日志
endTime=$(date +"%Y年%m月%d日 %H:%M:%S")
echo "开始:$beginTime 结束:$endTime $gzDumpFile 备份成功" >> $logFile
# 清理旧备份
delFile=$(ls -l -crt $bakDir/*.tar.gz | awk '{print $9}' | head -1)
count=$(ls -l -crt $bakDir/*.tar.gz | awk '{print $9}' | wc -l)
if [ -n "$delFile" ] && [ "$count" -gt $backNumber ]; then
rm -f "$delFile"
echo "$(date +"%Y-%m-%d %H:%M:%S") 删除旧备份文件 $delFile" >> $logFile
fi
关键参数说明:
--single-transaction:确保备份时的事务一致性--quick:优化大表备份性能rm -f:静默删除,避免文件不存在时报错bash复制# 创建备份目录
sudo mkdir -p /opt/back/log
# 设置目录权限(根据实际用户调整)
sudo chown -R $(whoami):$(whoami) /opt/back
sudo chmod -R 755 /opt/back
# 创建脚本文件
sudo nano /opt/backup-mysql.sh
# 粘贴上述脚本内容后保存
# 赋予执行权限
sudo chmod +x /opt/backup-mysql.sh
问题1:执行时报错^M: command not found
bash复制sed -i 's/\r$//' /opt/backup-mysql.sh
问题2:mysqldump连接失败
问题3:备份文件大小为0
每天凌晨2点执行备份:
bash复制0 2 * * * /opt/backup-mysql.sh >> /opt/back/log/cron.log 2>&1
配置步骤:
bash复制crontab -e
# 添加上述行后保存退出
# 查看现有任务
crontab -l
bash复制* * * * * /opt/backup-mysql.sh >> /opt/back/log/cron.log 2>&1
bash复制tail -f /opt/back/log/cron.log
bash复制PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
添加备份后校验步骤:
bash复制# 在脚本末尾添加
if gzip -t "$gzDumpFile"; then
echo "备份文件校验成功" >> "$logFile"
else
echo "警告:备份文件校验失败!" >> "$logFile"
# 可以添加邮件或钉钉报警
fi
将备份同步到远程存储:
bash复制# 使用rsync同步到远程服务器
rsync -avz /opt/back/ user@remote:/path/to/backup/
# 或使用云存储工具
rclone copy /opt/back remote:bucket_name
对于大型数据库:
--skip-lock-tables参数(非InnoDB表需要)--where条件分批备份bash复制chmod 600 /opt/back/*.tar.gz
bash复制# /etc/logrotate.d/mysql-backup
/opt/back/log/*.log {
daily
rotate 30
compress
missingok
notifempty
}
这套方案在我负责的多个生产环境中稳定运行超过3年,经历过多次真实的数据恢复场景验证。关键是要定期测试备份文件的恢复流程,确保在真正需要时能够发挥作用。