基于 Shell 的本地数据库一键备份与恢复
在日常全栈开发与生产运维中,数据库数据的安全性是悬在所有工程师头顶的达摩克利斯之剑:
- 本地执行测试脚本时不小心
DROP掉了一张重要的数据表; - 生产环境执行版本升级前,需要对当前线上数据库做一次秒级的快照备份;
- 需要快速将生产环境的脱敏数据一键同步到本地开发环境进行复杂 Bug 复现。
很多团队依赖庞大复杂的第三方备份 SaaS 工具,配置繁琐且存在网络权限暴露的风险。
用不到 30 行纯净严谨的 Bash Shell 脚本,配合 Docker 原生命令,我们可以打造一套秒级备份、自动 gzip 压缩、支持一键全量恢复的极简数据库容灾工具。
极简备份脚本实现(scripts/db-backup.sh)
#!/bin/bash set -euo pipefail # 基础配置 CONTAINER_NAME="star-postgres" DB_USER="star_dev" DB_NAME="star_app" BACKUP_DIR="./.backups/db" TIMESTAMP=$(date +"%Y%m%d_%H%M%S") BACKUP_FILE="${BACKUP_DIR}/backup_${DB_NAME}_${TIMESTAMP}.sql.gz" mkdir -p "${BACKUP_DIR}" echo "📦 正在执行数据库 [${DB_NAME}] 全量快照备份..." # 1. 导出数据并实时通过 gzip 压缩 docker exec "${CONTAINER_NAME}" pg_dump -U "${DB_USER}" "${DB_NAME}" | gzip > "${BACKUP_FILE}" FILE_SIZE=$(ls -lh "${BACKUP_FILE}" | awk '{print $5}') echo "✅ 备份成功!备份文件: ${BACKUP_FILE} (体积: ${FILE_SIZE})" # 2. 自动清理机制:本地仅保留最近 10 次历史备份,防止撑爆磁盘 echo "🧹 正在清理超过 10 个的陈旧备份快照..." ls -t "${BACKUP_DIR}"/backup_*.sql.gz | tail -n +11 | xargs -I {} rm -- "{}" 2>/dev/null || true echo "✨ 备份收尾完毕!"极简一键恢复脚本实现(scripts/db-restore.sh)
当发生误操作或需要回滚到特定快照时,执行一键恢复:
#!/bin/bash set -euo pipefail CONTAINER_NAME="star-postgres" DB_USER="star_dev" DB_NAME="star_app" BACKUP_DIR="./.backups/db" # 检查是否存在备份文件 LATEST_BACKUP=$(ls -t "${BACKUP_DIR}"/backup_*.sql.gz 2>/dev/null | head -n 1 || true) if [ -z "${LATEST_BACKUP}" ]; then echo "❌ 错误: 未在 ${BACKUP_DIR} 中找到任何可用的备份文件!" exit 1 fi TARGET_FILE="${1:-$LATEST_BACKUP}" echo "⚠️ [高危警告] 即将使用快照 [${TARGET_FILE}] 覆盖当前数据库 [${DB_NAME}]!" read -p "确认继续执行覆盖恢复吗?(y/N): " confirm if [[ ! "$confirm" =~ ^[yY]$ ]]; then echo "操作已取消。" exit 0 fi echo "🔄 正在执行解压与全量数据库恢复..." # 1. 终止已有活动连接,防止锁冲突 docker exec "${CONTAINER_NAME}" psql -U "${DB_USER}" -d postgres -c \ "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${DB_NAME}' AND pid <> pg_backend_pid();" > /dev/null # 2. 重建干净数据库并导入 docker exec "${CONTAINER_NAME}" psql -U "${DB_USER}" -d postgres -c "DROP DATABASE IF EXISTS ${DB_NAME};" > /dev/null docker exec "${CONTAINER_NAME}" psql -U "${DB_USER}" -d postgres -c "CREATE DATABASE ${DB_NAME};" > /dev/null gunzip -c "${TARGET_FILE}" | docker exec -i "${CONTAINER_NAME}" psql -U "${DB_USER}" -d "${DB_NAME}" > /dev/null echo "🎉 数据库恢复成功!数据已完全还原至快照时间点。"生产集成与定时任务(Crontab)
在生产服务器上,只需在crontab -e中配置一行定时任务:
# 每天凌晨 03:00 自动执行一次数据库冷备 0 3 * * * /bin/bash /opt/star-app/scripts/db-backup.sh >> /var/log/db_backup.log 2>&1配合rclone或云厂商 CLI,可顺手将压缩包同步至跨区域的云存储冷归档中,每月存储成本不到 1 块钱。
总结
真正的安全感,来自于底层的极简与可控。
不到 30 行纯粹的 Shell 脚本,把数据库备份与灾难恢复做到极致轻量、透明可靠。