MySQL自动备份与覆盖恢复实战指南

 更新时间:2026年03月11日 09:12:32   作者:波哦波  
本文详细描述了如何使用SQL备份文件恢复MySQL数据库的过程,包括查询当前数据库的字符集和排序规则、创建恢复前备份目录、备份现有数据库、删除旧库、重建新库、使用备份文件覆盖恢复、以及恢复后的检查和测试,需要的朋友可以参考下

一、此前每日备份的脚本

#!/bin/bash

# === 配置部分 ===
BACKUP_BASE_DIR="/data/backup_mysql"
DATE=$(date +%F)
LOG_FILE="${BACKUP_BASE_DIR}/logs/backup-${DATE}.log"
LOCK_FILE="/tmp/mysql_backup.lock"

# 备份选项(1=启用,0=禁用)
ENABLE_FULL_BACKUP=1
ENABLE_PER_DB_BACKUP=1

# === 日志重定向 ===
mkdir -p "${BACKUP_BASE_DIR}/logs"
exec >> "$LOG_FILE" 2>&1

echo "===== MySQL Backup Started: $(date) ====="

# === 加锁,避免重复执行 ===
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
  echo "❗️ 另一个备份任务正在运行,退出..."
  exit 1
fi

# === 全量备份 ===
if [ "$ENABLE_FULL_BACKUP" -eq 1 ]; then
  echo "📦 开始全库备份..."
  FULL_BACKUP_FILE="${BACKUP_BASE_DIR}/all/all-databases-${DATE}.sql"
  FULL_GZ_FILE="${FULL_BACKUP_FILE}.gz"
  mkdir -p "${BACKUP_BASE_DIR}/all"

  mysqldump --all-databases --single-transaction --quick --lock-tables=false > "$FULL_BACKUP_FILE"

  if [ $? -eq 0 ]; then
    echo "✔ 全库备份成功: $FULL_BACKUP_FILE"
    gzip "$FULL_BACKUP_FILE"
    if [ $? -eq 0 ]; then
      echo "✔ 全库压缩成功: $FULL_GZ_FILE"
    else
      echo "✘ 全库压缩失败: $FULL_BACKUP_FILE" >&2
    fi
  else
    echo "✘ 全库备份失败" >&2
    rm -f "$FULL_BACKUP_FILE"
  fi
fi

# === 每库备份 ===
if [ "$ENABLE_PER_DB_BACKUP" -eq 1 ]; then
  echo "📂 开始库级别备份..."
  databases=$(mysql -e "SHOW DATABASES;" | grep -Ev "^(Database|information_schema|performance_schema|mysql|sys)$")

  for db in $databases; do
    echo "🔄 正在备份: $db"
    DB_BACKUP_DIR="${BACKUP_BASE_DIR}/${db}"
    mkdir -p "$DB_BACKUP_DIR"
    DB_BACKUP_FILE="${DB_BACKUP_DIR}/${db}-${DATE}.sql"
    DB_GZ_FILE="${DB_BACKUP_FILE}.gz"

    mysqldump --single-transaction --quick --lock-tables=false "$db" > "$DB_BACKUP_FILE"

    if [ $? -eq 0 ]; then
      echo "✔ 备份成功: $DB_BACKUP_FILE"
      gzip "$DB_BACKUP_FILE"
      if [ $? -eq 0 ]; then
        echo "✔ 压缩成功: $DB_GZ_FILE"
      else
        echo "✘ 压缩失败: $DB_BACKUP_FILE" >&2
      fi
    else
      echo "✘ 备份失败: $db" >&2
      rm -f "$DB_BACKUP_FILE"
    fi
  done
fi

# === 清理过期文件(.sql / .sql.gz) ===
echo "🧹 清理 7 天前的备份文件..."
find "$BACKUP_BASE_DIR" -type f \( -name "*.sql" -o -name "*.sql.gz" \) -mtime +7 -exec rm -f {} \;

echo "===== MySQL Backup Completed: $(date) ====="

二、环境信息

  • 服务器主机名:
  • 服务器 IP:
  • 数据库类型:MySQL
  • MySQL 版本:8.0.42 Community Server
  • 目标数据库:imip_ecb
  • 数据库字符集:utf8mb4
  • 排序规则:utf8mb4_general_ci
  • 备份文件路径(恢复来源):
  • /data/backup_mysql/imip_ecb/imip_ecb-2025-12-11.sql.gz
  • 恢复前保护性备份路径:
    /data/backup_mysql/manual_before_restore/imip_ecb-before-restore-2025-12-11.sql
  • 恢复类型:覆盖源库恢复(在同一实例上,用备份覆盖原有 imip_ecb 库)

三、实际恢复操作步骤

1. 查询imip_ecb数据库字符集与排序规则

mysql -u root -p -e "
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME='imip_ecb';
"

查询结果:

SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME
----------- | -------------------------- | ------------------------
imip_ecb    | utf8mb4                    | utf8mb4_general_ci

目的:记录当前库的字符集/排序规则,确保重建数据库时保持一致。

2. 创建“恢复前快照”备份目录

mkdir -p /data/backup_mysql/manual_before_restore

目的:单独存放本次覆盖前的手工备份,便于必要时回滚。

3. 对覆盖前的imip_ecb做一次完整逻辑备份

mysqldump --single-transaction --quick --lock-tables=false \
  imip_ecb > /data/backup_mysql/manual_before_restore/imip_ecb-before-restore-`date +%F`.sql

确认备份文件存在:

cd /data/backup_mysql/manual_before_restore
ll
# imip_ecb-before-restore-2025-12-11.sql

目的:为本次覆盖恢复保留一份“恢复前状态”的 SQL 备份。

4. 删除原有imip_ecb数据库(为覆盖恢复做准备)

mysql -u root -p -e "DROP DATABASE IF EXISTS imip_ecb;"

目的:清理旧库,避免恢复过程中与原有对象冲突,确保是“重建 + 导入”的干净覆盖。

5. 按原字符集/排序规则重建imip_ecb数据库

mysql -u root -p -e "
CREATE DATABASE imip_ecb
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_general_ci;
"

目的:与恢复前字符集/排序规则保持一致,避免编码相关问题。

6. 使用 2025-12-11 备份文件对imip_ecb进行覆盖恢复

zcat /data/backup_mysql/imip_ecb/imip_ecb-2025-12-11.sql.gz \
  | mysql -u root -p imip_ecb

目的:通过 zcat 解压 .sql.gz,并通过管道将逻辑备份数据导入到新建的 imip_ecb 库,实现在源实例上的覆盖恢复

7. 恢复后检查:确认数据库存在

mysql -u root -p -e "SHOW DATABASES LIKE 'imip_ecb';"

8. 恢复后检查:确认业务表已成功恢复

mysql -u root -p -D imip_ecb -e "SHOW TABLES;"

输出包含业务表,例如:

EMS_EQUIPMENT_INFO
EMS_INSPECT_TASK
EMS_MAINTENANCE_WORK_ORDER
ERP_STOCK
ERP_STOCK_IN
ERP_STOCK_OUT
ERP_SUPPLIER
ERP_WAREHOUSE
infra_task_attachment
...

目的:确认 EMS/ERP 相关业务表均已从备份中成功恢复,库结构完整。

以上就是MySQL自动备份与覆盖恢复实战指南的详细内容,更多关于MySQL自动备份与覆盖恢复的资料请关注脚本之家其它相关文章!

相关文章

  • Mysql优化调优中两个重要参数table_cache和key_buffer

    Mysql优化调优中两个重要参数table_cache和key_buffer

    这篇文章主要介绍了Mysql优化调优中两个重要参数table_cache和key_buffer,需要的朋友可以参考下
    2014-12-12
  • MySQL自动填充create_time和update_time的两种方式

    MySQL自动填充create_time和update_time的两种方式

    当我们创建业务表的时候 通常都需要设置create_time 和 update_time,下面这篇文章主要给大家介绍了关于MySQL自动填充createTime和updateTime的两种方式,需要的朋友可以参考下
    2022-05-05
  • MySQL8新特性:自增主键的持久化详解

    MySQL8新特性:自增主键的持久化详解

    MySQL8.0 GA版本发布了,展现了众多新特性,下面这篇文章主要给大家介绍了关于MySQL8新特性:自增主键的持久化的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-07-07
  • MySQL max_allowed_packet的坑

    MySQL max_allowed_packet的坑

    max_allowed_packet是 MySQL 中的一个设定参数,用于设定所接受的包的大小,根据情形不同,其缺省值可能是 1M 或者 4M,本文主要介绍了MySQL max_allowed_packet的坑,感兴趣的可以了解一下
    2024-01-01
  • MySQL 导出一条数据的插入语句(示例详解)

    MySQL 导出一条数据的插入语句(示例详解)

    在MySQL中,如果我们想要导出一条数据的插入语句,我们可以使用SELECT ... INTO OUTFILE语句,这篇文章主要介绍了MySQL 导出一条数据的插入语句,需要的朋友可以参考下
    2024-06-06
  • Mysql存储json格式的实现

    Mysql存储json格式的实现

    本文主要介绍了Mysql存储json格式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • MySQL自动停机的问题处理实战记录

    MySQL自动停机的问题处理实战记录

    这篇文章主要给大家介绍了关于MySQL自动停机的问题处理,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-05-05
  • GROUP_CONCAT的用法

    GROUP_CONCAT的用法

    GROUP_CONCAT的用法...
    2006-12-12
  • MySQL 服务和数据库管理

    MySQL 服务和数据库管理

    今天MySQL总结一些方法和一些基础的内容,下面文章将围绕MySQL 服务与数据库管理得相关资料展开内容,需要的朋友可以参考一下,希望对你有所帮助
    2021-11-11
  • Win10系统下MySQL8.0.16 压缩版下载与安装教程图解

    Win10系统下MySQL8.0.16 压缩版下载与安装教程图解

    这篇文章主要介绍了Win10系统下MySQL8.0.16 压缩版下载与安装教程图解,本文图文并茂给大家介绍的非常详细,具有一定的参考解决价值,需要的朋友可以参考下
    2019-06-06

最新评论