本文目录导读:

我来提供一个完整的数据库整库定时备份方案,主要针对MySQL数据库。
Linux下MySQL备份脚本
基础备份脚本
#!/bin/bash
# 数据库配置
DB_HOST="localhost"
DB_USER="root"
DB_PASS="your_password"
DB_NAME="your_database"
BACKUP_DIR="/data/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
mysqldump -h$DB_HOST -u$DB_USER -p$DB_PASS \
--single-transaction \
--routines \
--triggers \
--events \
--databases $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "备份成功: ${DB_NAME}_${DATE}.sql.gz"
echo "备份文件大小: $(du -h $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz | cut -f1)"
else
echo "备份失败!"
# 发送告警通知
echo "数据库备份失败" | mail -s "备份告警" admin@example.com
fi
# 删除旧备份,保留最近N天
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "已清理${RETENTION_DAYS}天前的旧备份"
优化版备份脚本(支持多数据库)
#!/bin/bash
# 配置
CONFIG_FILE="/etc/db_backup.conf"
LOG_FILE="/var/log/db_backup.log"
BACKUP_BASE="/data/backup/mysql"
RETENTION_DAYS=7
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# 加载配置
if [ -f "$CONFIG_FILE" ]; then
source $CONFIG_FILE
else
# 默认配置
DB_HOST="localhost"
DB_USER="root"
DB_PASS="password"
DB_LIST=("database1" "database2")
fi
# 初始化备份目录
mkdir -p $BACKUP_BASE/{daily,weekly,monthly}
# 获取当前时间
DATE=$(date +%Y%m%d_%H%M%S)
WEEKDAY=$(date +%u)
MONTHDAY=$(date +%d)
# 备份函数
backup_database() {
local db=$1
local backup_type=$2
local backup_path=$BACKUP_BASE/$backup_type
log "开始备份数据库: $db (类型: $backup_type)"
# 执行备份
if mysqldump -h$DB_HOST -u$DB_USER -p$DB_PASS \
--single-transaction \
--routines \
--triggers \
--events \
--databases $db | gzip > ${backup_path}/${db}_${DATE}.sql.gz; then
local file_size=$(du -h ${backup_path}/${db}_${DATE}.sql.gz | cut -f1)
log "备份成功: ${db}_${DATE}.sql.gz (大小: $file_size)"
return 0
else
log "备份失败: $db"
return 1
fi
}
# 主备份逻辑
log "=== 开始数据库备份 ==="
for db in "${DB_LIST[@]}"; do
# 每日备份
backup_database $db "daily"
# 每周日执行周备份
if [ $WEEKDAY -eq 7 ]; then
backup_database $db "weekly"
fi
# 每月1号执行月备份
if [ $MONTHDAY -eq 1 ]; then
backup_database $db "monthly"
fi
done
# 清理旧备份
log "清理旧备份..."
find $BACKUP_BASE/daily -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_BASE/weekly -name "*.sql.gz" -mtime +30 -delete
find $BACKUP_BASE/monthly -name "*.sql.gz" -mtime +365 -delete
log "=== 备份完成 ==="
配置文件示例 (/etc/db_backup.conf)
# 数据库连接配置
DB_HOST="localhost"
DB_USER="backup_user"
DB_PASS="secure_password"
# 要备份的数据库列表
DB_LIST=("mydb" "testdb" "production_db")
# 备份保留天数
RETENTION_DAYS=7
设置定时任务 (Crontab)
编辑crontab
# 编辑当前用户的crontab crontab -e # 或者编辑系统crontab sudo crontab -e
定时任务配置示例
# 每天凌晨2点执行备份 0 2 * * * /usr/local/bin/db_backup.sh # 每天凌晨2点和14点执行备份 0 2,14 * * * /usr/local/bin/db_backup.sh # 每天凌晨2点,并记录日志 0 2 * * * /usr/local/bin/db_backup.sh >> /var/log/backup_cron.log 2>&1 # 工作日(周一至周五)凌晨1点备份 0 1 * * 1-5 /usr/local/bin/db_backup.sh
配置权限和安全
创建专用备份用户
-- 在MySQL中创建备份专用用户 CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'secure_password'; GRANT SELECT, SHOW VIEW, RELOAD, REPLICATION CLIENT, EVENT, TRIGGER ON *.* TO 'backup_user'@'localhost'; FLUSH PRIVILEGES;
设置脚本权限
# 设置脚本权限 chmod 700 /usr/local/bin/db_backup.sh chmod 600 /etc/db_backup.conf # 创建日志目录 mkdir -p /var/log chmod 755 /var/log
高级功能脚本
压缩和加密备份
#!/bin/bash
# 加密备份
BACKUP_FILE="backup_$(date +%Y%m%d).sql"
ENCRYPT_PASSWORD="your_encryption_key"
# 备份并加密
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | \
gzip | \
openssl enc -aes-256-cbc -salt -pass pass:$ENCRYPT_PASSWORD > \
$BACKUP_DIR/${BACKUP_FILE}.gz.enc
# 解密命令
# openssl enc -d -aes-256-cbc -in backup.sql.gz.enc -pass pass:$ENCRYPT_PASSWORD | gunzip > backup.sql
备份验证和恢复测试
#!/bin/bash
# 验证备份文件
verify_backup() {
local backup_file=$1
echo "验证备份文件: $backup_file"
# 检查文件完整性
if gzip -t $backup_file 2>/dev/null; then
echo "✓ 压缩包完整性检查通过"
else
echo "✗ 压缩包损坏"
return 1
fi
# 检查SQL语法(解压后检查前1000行)
if gunzip -c $backup_file | head -1000 | mysql -u$DB_USER -p$DB_PASS --force -e "SOURCE /dev/stdin" 2>/dev/null; then
echo "✓ SQL语法检查通过"
else
echo "✗ SQL语法检查失败"
return 1
fi
return 0
}
远程备份(FTP/SFTP)
#!/bin/bash
# 远程备份配置
REMOTE_HOST="backup.example.com"
REMOTE_USER="backup_user"
REMOTE_PASS="remote_password"
REMOTE_PATH="/backup/mysql"
# 使用lftp进行FTP备份
lftp -u $REMOTE_USER,$REMOTE_PASS $REMOTE_HOST <<EOF
cd $REMOTE_PATH
put $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
quit
EOF
# 或者使用SCP(更安全)
scp -i /path/to/ssh_key $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz \
${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/
监控和告警
简单的监控脚本
#!/bin/bash
# 监控备份状态
CHECK_TIME=$(date -d "24 hours ago" +%Y%m%d)
LATEST_BACKUP=$(ls -t $BACKUP_DIR/*.sql.gz 2>/dev/null | head -1)
if [ -z "$LATEST_BACKUP" ] || [ $(stat -c %Y "$LATEST_BACKUP") -lt $(date -d "24 hours ago" +%s) ]; then
echo "警告: 24小时内无备份文件" | mail -s "备份监控告警" admin@example.com
fi
最佳实践建议
- 测试恢复流程:定期测试备份文件的恢复能力
- 多地备份:同时备份到本地和远程服务器
- 日志记录:记录备份成功/失败状态
- 监控告警:设置备份失败的告警通知
- 性能影响:在业务低峰期执行备份
- 文件命名:包含日期时间,便于管理
- 定期清理:设置合理的保留策略
这个完整的解决方案可以根据你的具体需求进行调整和扩展。