针对 InnoDB 表损坏场景的自动导出脚本方案
                           
天天向上
发布: 2025-07-06 14:17:50

原创
524 人浏览过

下面是一个针对 InnoDB 表损坏场景的自动导出脚本方案,结合 innodb_force_recovery 参数,支持自动挂起 MySQL 服务、设置恢复模式、导出所有可读取表的数据,再清理恢复配置,安全恢复数据。


使用场景

适用于以下情况:

  • MySQL 无法正常启动,提示 InnoDB 表空间损坏
  • 某些表报错:InnoDB: corruption, page checksum mismatch
  • 无法进入数据目录正常操作,但希望尽可能导出数据而不是直接删库

一、原理说明

  • innodb_force_recovery 是 InnoDB 提供的“应急启动模式”
  • 范围从 1~6,数字越大,越危险(会跳过更多恢复逻辑)
  • 可用性原则:尽量从低级别(1)尝试,逐步提高

🚨 强提醒>= 4 时会禁止写操作,只能用于导出,不能用于线上写入!


二、自动导出脚本(推荐用 bash)

脚本:innodb_auto_dump.sh

#!/bin/bash

# ==== 配置项 ====
MYSQL_CNF="/etc/my.cnf"
BACKUP_DIR="/data/innodb_force_dump/$(date +%F_%H%M)"
MYSQL_USER="root"
MYSQL_PASS="your_password"

# ==== Step 1. 停止 MySQL ====
echo "[INFO] 停止 MySQL 服务..."
systemctl stop mysqld

# ==== Step 2. 设置恢复模式 ====
echo "[INFO] 设置 innodb_force_recovery = 3..."
sed -i '/^\[mysqld\]/a innodb_force_recovery=3' $MYSQL_CNF

# ==== Step 3. 启动 MySQL ====
echo "[INFO] 启动 MySQL 服务 (应急模式)..."
systemctl start mysqld
sleep 5

# 检查是否启动成功
if ! mysqladmin ping -u$MYSQL_USER -p$MYSQL_PASS >/dev/null 2>&1; then
  echo "[ERROR] MySQL 启动失败,请尝试更高等级的 recovery。"
  exit 1
fi

# ==== Step 4. 自动导出所有数据库 ====
mkdir -p "$BACKUP_DIR"
echo "[INFO] 导出所有数据库数据至 $BACKUP_DIR ..."

# 获取用户数据库(排除系统库)
DBS=$(mysql -u$MYSQL_USER -p$MYSQL_PASS -Nse \
    "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('mysql','performance_schema','information_schema','sys');")

for DB in $DBS; do
  echo "[INFO] 导出数据库:$DB"
  mkdir -p "$BACKUP_DIR/$DB"
  mysqldump -u$MYSQL_USER -p$MYSQL_PASS \
    --single-transaction --skip-lock-tables --quick \
    $DB > "$BACKUP_DIR/$DB.sql"

  if [[ $? -ne 0 ]]; then
    echo "[WARN] 导出失败:$DB" >> "$BACKUP_DIR/errors.log"
  fi
done

# ==== Step 5. 恢复正常模式 ====
echo "[INFO] 移除恢复模式,准备重建数据库..."
sed -i '/innodb_force_recovery/d' $MYSQL_CNF

systemctl stop mysqld
sleep 5
systemctl start mysqld

# ==== Step 6. 完成提示 ====
echo "[OK] InnoDB 应急导出完成,备份位置:$BACKUP_DIR"
echo "请检查 backup 中的 .sql 文件进行后续恢复操作。"

三、恢复已导出数据

恢复过程建议在清空或新数据库上执行:

mysql -u root -p < /data/innodb_force_dump/2025-07-06_1130/mydb.sql

四、建议的恢复流程图

发现损坏
   ↓
修改 my.cnf:innodb_force_recovery=1
   ↓
若无法启动 → 提高至 3、4...
   ↓
启动成功 → 导出数据(推荐 mysqldump)
   ↓
移除恢复配置,重启 MySQL
   ↓
新建数据库 → 导入数据

五、关于 innodb_force_recovery 参数详解

等级行为风险
1跳过 Insert Buffer 恢复安全
2跳过 Redo 日志应用安全
3忽略 Undo 日志(可读脏数据)可接受
4跳过 Purge 操作会有垃圾数据残留
5跳过后台线程启动严重不一致风险
6禁用所有恢复,允许读表最后手段,可能破坏数据结构

六、官方与推荐参考


七、风险提醒与建议

项目建议
正式环境中操作前请备份数据目录tar -czf /backup/mysql_data.tgz /var/lib/mysql
导出过程建议执行后手动校验每个 SQL 文件检查是否缺表或为空
如使用系统服务,请用 systemctl 管理 mysqld避免 kill -9
导出失败可以配合 mysqlpumpmydumper 重试增加稳定性

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *