2026年01月20日/ 浏览 12
本人亲测可用
在日常业务场景,通常情况下,我们不需要进行全库备份,而是只备份需要的数据库。本文分享一个MySQL数据库备份恢复脚本,用于备份和恢复指定的数据库。

备份目录结构如下:
mysql-backup/ └── YYYYMMDD_HHMMSS/ ├── backup.log ├── db1/ │ ├── table1.sql │ ├── table2.sql │ └── ... ├── db2/ │ ├── table1.sql │ ├── table2.sql │ └── ... └── ...其中:
-YYYYMMDD_HHMMSS 是备份时间戳(年、月、日、时、分、秒) backup.log 是备份过程的日志文件 每个数据库都有自己的目录,目录名与数据库名相同 每个表都以 .sql 文件格式单独备份,文件名与表名相同这个恢复脚本是和上面备份脚本配套使用的,用于恢复指定数据库的备份。只能恢复一个数据库,但是也够用了。
restore-onedb.sh#!/bin/bash # MySQL 连接参数 MYSQL_HOST="127.0.0.1" MYSQL_PORT="3306" MYSQL_USER="root" MYSQL_PASS="your_mysql_password" # 检查参数 if [ $# -ne 2 ]; then echo "用法: $0 <备份目录路径> <数据库名>" echo "例如: $0 /opt/mysql-backup/20231201_143022 mydatabase" exit 1 fi BACKUP_DIR="$1" DB_NAME="$2" DB_BACKUP_DIR="$BACKUP_DIR/$DB_NAME" # 检查备份目录和数据库备份是否存在 if [ ! -d "$BACKUP_DIR" ]; then echo "错误: 备份目录不存在: $BACKUP_DIR" exit 1 fi if [ ! -d "$DB_BACKUP_DIR" ]; then echo "错误: 在备份目录中未找到数据库 $DB_NAME 的备份" echo "可用的数据库备份:" find "$BACKUP_DIR" -maxdepth 1 -type d -not -path "$BACKUP_DIR" -not -name ".*" -exec basename {} \; | grep -v -E "(backup|log)" exit 1 fi echo "开始恢复指定数据库" echo "备份目录: $BACKUP_DIR" echo "数据库名: $DB_NAME" echo "MySQL 主机: $MYSQL_HOST:$MYSQL_PORT" echo "==========================================" # 确认操作 read -p "确认要恢复数据库 $DB_NAME 吗?这将删除现有数据库并重新导入!(y/N): " confirm case "$confirm" in [yY]|[yY][eE][sS]) echo "开始恢复..." ;; *) echo "操作已取消" exit 0 ;; esac # 记录整个恢复过程的开始时间 OVERALL_START_TIME=$(date +%s) # 检查数据库是否存在 DB_EXISTS=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \ -e "SHOW DATABASES LIKE ${DB_NAME};" -s --skip-column-names 2>/dev/null) if [ -n "$DB_EXISTS" ]; then echo "数据库 $DB_NAME 已存在,正在删除..." mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \ -e "DROP DATABASE \`${DB_NAME}\`;" 2>/dev/null if [ $? -ne 0 ]; then echo "错误: 无法删除数据库 $DB_NAME" exit 1 fi echo "数据库 $DB_NAME 已成功删除" fi # 创建新数据库 echo "创建数据库 $DB_NAME..." mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \ -e "CREATE DATABASE \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null if [ $? -ne 0 ]; then echo "错误: 无法创建数据库 $DB_NAME" exit 1 fi # 恢复所有表 TABLE_COUNT=0 FAILED_COUNT=0 echo "开始恢复表数据..." echo "------------------------------------------" for TABLE_FILE in "$DB_BACKUP_DIR"/*.sql; do if [ -f "$TABLE_FILE" ]; then TABLE_NAME=$(basename "$TABLE_FILE" .sql) # 记录单个表恢复的开始时间 TABLE_START_TIME=$(date +%s) # 获取SQL文件大小 FILE_SIZE=$(du -h "$TABLE_FILE" | cut -f1) echo "恢复表: $DB_NAME.$TABLE_NAME (文件大小: $FILE_SIZE)" # 恢复表 mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \ "$DB_NAME" < "$TABLE_FILE" if [ $? -eq 0 ]; then # 记录单个表恢复的结束时间 TABLE_END_TIME=$(date +%s) TABLE_DURATION=$((TABLE_END_TIME - TABLE_START_TIME)) # 查询表的行数 ROW_COUNT=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \ -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`${TABLE_NAME}\`;" -s --skip-column-names 2>/dev/null) if [ $? -eq 0 ]; then echo "✓ 成功恢复表: $DB_NAME.$TABLE_NAME | 耗时: ${TABLE_DURATION}秒 | 行数: $ROW_COUNT" else echo "✓ 成功恢复表: $DB_NAME.$TABLE_NAME | 耗时: ${TABLE_DURATION}秒 | 行数: 查询失败" fi TABLE_COUNT=$((TABLE_COUNT + 1)) else echo "✗ 错误: 恢复表 $DB_NAME.$TABLE_NAME 失败" FAILED_COUNT=$((FAILED_COUNT + 1)) fi fi done # 记录整个恢复过程的结束时间 OVERALL_END_TIME=$(date +%s) OVERALL_DURATION=$((OVERALL_END_TIME - OVERALL_START_TIME)) echo "==========================================" echo "数据库 $DB_NAME 恢复完成!" echo "成功恢复表: $TABLE_COUNT 个" if [ $FAILED_COUNT -gt 0 ]; then echo "恢复失败表: $FAILED_COUNT 个" fi echo "总耗时: ${OVERALL_DURATION} 秒" echo "备份目录: $BACKUP_DIR" # 显示数据库总行数统计 echo "------------------------------------------" echo "数据库行数统计:" TOTAL_ROWS=0 for TABLE_FILE in "$DB_BACKUP_DIR"/*.sql; do if [ -f "$TABLE_FILE" ]; then TABLE_NAME=$(basename "$TABLE_FILE" .sql) ROW_COUNT=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \ -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`${TABLE_NAME}\`;" -s --skip-column-names 2>/dev/null) if [ $? -eq 0 ] && [ -n "$ROW_COUNT" ]; then echo " $TABLE_NAME: $ROW_COUNT 行" TOTAL_ROWS=$((TOTAL_ROWS + ROW_COUNT)) fi fi done echo " 总计: $TOTAL_ROWS 行"该恢复脚本设计用于恢复单个数据库的备份,并提供了完善的错误处理、用户交互和统计功能。
记录了整个恢复过程的开始和结束时间,以及每个表恢复的单独时间,便于性能分析和优化,特别是在处理大型数据库时。脚本会检查目标数据库是否存在,如果存在则先删除再创建,确保恢复环境干净。创建数据库时指定了字符集和排序规则为utf8mb4,支持完整的Unicode字符,确保数据编码正确性。脚本会查询每个恢复后的表的行数,用于验证数据恢复的完整性。