MySQL定时备份脚本,自动删除旧备份

前言

数据库数据很重要,必须每天自动备份。写个备份脚本,自动备份+自动删旧的,不用手动管。

一、备份脚本

完整脚本 backup_mysql.sh

#!/bin/bash

# MySQL配置
DB_USER="root"
DB_PASS="your_password"
DB_NAME="mydb"

# 备份目录
BACKUP_DIR="/data/backup/mysql"

# 保留天数
KEEP_DAYS=7

# 日期
DATE=$(date +%Y%m%d_%H%M%S)

# 备份文件名
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"

# 创建目录
mkdir -p $BACKUP_DIR

# 备份并压缩
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_FILE

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo "[$(date)] 备份成功: $BACKUP_FILE"
else
    echo "[$(date)] 备份失败!"
    exit 1
fi

# 删除7天前的旧备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +$KEEP_DAYS -delete

echo "[$(date)] 旧备份清理完成"

二、脚本说明

各部分解释

部分 说明
DB_USER 数据库用户名
DB_PASS 数据库密码
DB_NAME 要备份的数据库名
BACKUP_DIR 备份存放目录
KEEP_DAYS 保留几天的备份
mysqldump 备份命令
gzip 压缩,节省空间
find -mtime +7 找7天前的文件删除

备份全部数据库

mysqldump -u$DB_USER -p$DB_PASS --all-databases | gzip > $BACKUP_FILE

备份多个数据库

mysqldump -u$DB_USER -p$DB_PASS --databases db1 db2 db3 | gzip > $BACKUP_FILE

三、设置执行权限

chmod +x /data/backup/backup_mysql.sh

四、测试脚本

/data/backup/backup_mysql.sh

看有没有备份文件生成:

ls -lh /data/backup/mysql/

五、设置定时任务

每天凌晨3点备份

crontab -e

添加:

0 3 * * * /data/backup/backup_mysql.sh >> /data/backup/backup.log 2>&1

说明:

  • 0 3 * * * 每天凌晨3点
  • >> backup.log 输出写到日志
  • 2>&1 错误也写进去

查看定时任务

crontab -l

六、备份文件恢复

恢复步骤

# 解压
gunzip < mydb_20261008_030000.sql.gz | mysql -u root -p mydb

或者先解压再恢复

# 解压
gunzip mydb_20261008_030000.sql.gz

# 恢复
mysql -u root -p mydb < mydb_20261008_030000.sql

七、更完善的脚本

带日志和邮件通知的版本

#!/bin/bash

DB_USER="root"
DB_PASS="your_password"
DB_NAME="mydb"
BACKUP_DIR="/data/backup/mysql"
KEEP_DAYS=7
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
LOG_FILE="$BACKUP_DIR/backup.log"

mkdir -p $BACKUP_DIR

echo "========== $(date) 开始备份 ==========" >> $LOG_FILE

# 备份
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME 2>>$LOG_FILE | gzip > $BACKUP_FILE

if [ $? -eq 0 ]; then
    FILE_SIZE=$(ls -lh $BACKUP_FILE | awk '{print $5}')
    echo "[$(date)] 备份成功,文件大小: $FILE_SIZE" >> $LOG_FILE
else
    echo "[$(date)] 备份失败!" >> $LOG_FILE
    # 这里可以加邮件通知
    exit 1
fi

# 删除旧备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
echo "[$(date)] 清理 $KEEP_DAYS 天前的旧备份完成" >> $LOG_FILE

echo "========== $(date) 备份结束 ==========" >> $LOG_FILE

常见坑

坑1:密码写在脚本里不安全

脚本里明文写了数据库密码。

解决: 用mysql配置文件:

# /root/.my.cnf
[client]
user=root
password=your_password

然后脚本里就不用写密码了:

mysqldump $DB_NAME | gzip > $BACKUP_FILE

设置权限:

chmod 600 /root/.my.cnf

坑2:备份文件太大

不压缩的话备份文件很大。

解决: 用gzip压缩,能压缩到原来的1/10。

坑3:定时任务不执行

cron里写了脚本,但没执行。

原因:

  1. 脚本没加执行权限
  2. 路径写错了
  3. 环境变量不对

解决: 脚本里用全路径,比如 /usr/bin/mysqldump。

坑4:备份完没验证

备份文件损坏了都不知道。

解决: 定期找个测试库恢复一下,看备份能不能用。

坑5:备份文件存在同一台服务器

服务器挂了,备份也没了。

解决: 把备份传到远程服务器或OSS。

# 传到远程服务器
scp $BACKUP_FILE root@192.168.1.20:/data/backup/

总结

备份三步走:

  1. 写备份脚本(mysqldump + gzip + find删旧)
  2. 加执行权限
  3. 加crontab定时任务

记住: 备份不是备份了就完了,要定期验证能不能恢复!

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:59