本文目录导读:

实现数据库自动恢复脚本,需要视你的数据库类型(如 MySQL、PostgreSQL、SQL Server)和备份文件格式(如 SQL 文件、压缩包)而定,以下是通用的Bash 脚本思路及针对 MySQL 的示例,其他数据库可参考类似逻辑。
核心步骤(以 MySQL 为例)
- 检查备份文件是否存在
- 停止目标服务(可选) – 避免恢复期间数据写入冲突
- 解压备份文件(如果压缩)
- 使用
mysql命令恢复数据 - 重启服务(如果之前停止)
- 记录日志
示例脚本(自动恢复 MySQL 数据库)
#!/bin/bash
# ===== 配置参数 =====
BACKUP_DIR="/data/backup/mysql" # 备份文件存放目录
DB_NAME="your_database_name" # 目标数据库名称
DB_USER="root" # 数据库用户(需有创建/恢复权限)
DB_PASS="your_password" # 数据库密码
MYSQL_CONTAINER="mysql_container" # 如果使用 Docker,填容器名;否则留空
DAYS_TO_KEEP=7 # 保留最近几天的备份文件
# 日志文件
LOG_FILE="/var/log/db_restore.log"
# ===== 函数:记录日志 =====
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# ===== 1. 查找最新的备份文件 =====
latest_backup=$(ls -t "$BACKUP_DIR"/*.sql 2>/dev/null | head -1)
if [ -z "$latest_backup" ]; then
# 如果没有 .sql 文件,尝试找压缩文件(.gz / .zip)
latest_archive=$(ls -t "$BACKUP_DIR"/*.sql.gz "$BACKUP_DIR"/*.zip 2>/dev/null | head -1)
if [ -z "$latest_archive" ]; then
log "ERROR: 未在 $BACKUP_DIR 中找到备份文件!"
exit 1
fi
# 解压
log "找到压缩备份: $latest_archive"
if [[ "$latest_archive" == *.gz ]]; then
gunzip -c "$latest_archive" > /tmp/restore_temp.sql
elif [[ "$latest_archive" == *.zip ]]; then
unzip -p "$latest_archive" > /tmp/restore_temp.sql
fi
BACKUP_FILE="/tmp/restore_temp.sql"
else
BACKUP_FILE="$latest_backup"
fi
log "开始恢复数据库,备份文件: $BACKUP_FILE"
# ===== 2. 停止服务(可选,根据实际需求决定) =====
if [ -n "$MYSQL_CONTAINER" ]; then
# Docker 容器场景
log "暂停容器内服务..."
docker exec "$MYSQL_CONTAINER" mysqladmin -u"$DB_USER" -p"$DB_PASS" shutdown
sleep 3
else
# 非 Docker:停止 MySQL 服务(需要 root 或 sudo 权限)
# systemctl stop mysql 或 service mysql stop
log "停止 MySQL 服务..."
# systemctl stop mysql
fi
# ===== 3. 恢复数据库 =====
# 首先用 mysql 命令清空目标数据库(可选但推荐重建)
if [ -n "$MYSQL_CONTAINER" ]; then
# Docker 方式恢复
docker exec -i "$MYSQL_CONTAINER" mysql -u"$DB_USER" -p"$DB_PASS" -e "DROP DATABASE IF EXISTS $DB_NAME; CREATE DATABASE $DB_NAME;"
docker exec -i "$MYSQL_CONTAINER" mysql -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$BACKUP_FILE"
else
# 直接本地恢复
mysql -u"$DB_USER" -p"$DB_PASS" -e "DROP DATABASE IF EXISTS $DB_NAME; CREATE DATABASE $DB_NAME;"
mysql -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$BACKUP_FILE"
fi
# 检查恢复结果
if [ $? -eq 0 ]; then
log "数据库 $DB_NAME 恢复成功!"
else
log "ERROR: 数据库恢复失败!"
# 清理临时文件
[ -f "/tmp/restore_temp.sql" ] && rm -f "/tmp/restore_temp.sql"
exit 1
fi
# ===== 4. 重启服务 =====
if [ -n "$MYSQL_CONTAINER" ]; then
docker start "$MYSQL_CONTAINER"
log "容器已重启。"
else
# systemctl start mysql
log "MySQL 服务已重启。"
fi
# ===== 5. 可选:删除临时文件 =====
[ -f "/tmp/restore_temp.sql" ] && rm -f "/tmp/restore_temp.sql"
# ===== 6. 清理旧备份文件(保留最近 N 天)=====
if command -v find &> /dev/null; then
find "$BACKUP_DIR" -name "*.sql" -o -name "*.sql.gz" -o -name "*.zip" -mtime +$DAYS_TO_KEEP -delete
log "已清理超过 $DAYS_TO_KEEP 天的旧备份。"
fi
log "自动恢复流程结束。"
exit 0
使用前注意事项
- 谨慎测试:先在测试环境执行,确保脚本不会误删生产库。
- 权限问题:脚本可能需要
root或mysql系统用户来操作,建议使用sudo或设置SUDO_USER。 - Docker 与非 Docker:脚本中通过
MYSQL_CONTAINER变量区分,留空则默认使用本地 MySQL 命令。 - 密码安全性:脚本内明文密码不安全,建议改用
~/.my.cnf配置文件或通过MYSQL_PWD环境变量(仍不完美,可考虑 Hashicorp Vault 等)。 - 自动执行:
- 如果需要定期自动恢复(例如灾备演练),可配合
crontab:# 每天凌晨 2 点执行(请修改脚本路径) 0 2 * * * /usr/local/bin/auto_restore_db.sh
- 警告:自动恢复会覆盖当前数据,请确认是你想要的结果(如从灾备恢复)。
- 如果需要定期自动恢复(例如灾备演练),可配合
其他数据库的恢复命令格式
| 数据库 | 恢复命令示例(恢复前通常需先创建空库) |
|---|---|
| PostgreSQL | pg_restore -U user -d dbname backup.dump 或 psql dbname < backup.sql |
| SQL Server | sqlcmd -S server -U user -P pass -d databasename -i backup.sql |
| MongoDB | mongorestore --db=yourdb /path/to/backup/ |
最后建议
- 不要 在生产环境直接使用未经测试的脚本。
- 备份脚本 也应同时保留(恢复脚本和备份脚本建议放在不同介质)。
- 定期手动演练恢复流程,确保备份文件在灾难发生时真正可用。
如果需要针对特定数据库或云服务(如 AWS RDS、阿里云 RDS)的恢复脚本,请提供更多细节,我可以进一步调整。