针对 InnoDB 表损坏场景的自动导出脚本方案
下面是一个针对 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 |
导出失败可以配合 mysqlpump 或 mydumper 重试 | 增加稳定性 |
更多详细内容请关注其他相关文章!