适配 Docker 容器的 InnoDB 崩溃恢复(innodb_force_recovery)注入与重启脚本方案
                           
天天向上
发布: 2025-07-06 14:22:12

原创
164 人浏览过

下面为你提供一套适配 Docker 容器的 InnoDB 崩溃恢复(innodb_force_recovery)注入与重启脚本方案,用于在容器化部署环境中出现 InnoDB 表损坏时应急导出数据。


场景说明

你可能遇到:

  • Docker 容器中的 MySQL 服务因 InnoDB 表损坏无法启动
  • 容器内无法直接修改 /etc/my.cnf 或挂载了外部配置
  • 希望临时注入 innodb_force_recovery 并完成应急数据导出

一、方法概览

方式优点缺点
1. 修改容器内配置文件 + 重启容器快速、适配现有容器修改容器内部状态
2. 使用环境变量挂载 my.cnf 文件适合有 volume 的场景要重建容器
3. 命令注入(exec 配置 + 临时执行)快速应急、脚本化不持久,需多步骤控制

下面提供的是第 1 种方式的脚本(最直接、最兼容)。


二、准备信息

假设:

  • Docker 容器名称为:mysql_docker
  • 数据目录默认 /var/lib/mysql
  • 用户名:root,密码:your_pass
  • 你需要将 innodb_force_recovery 设置为 3

三、应急导出脚本(容器版)

保存为:docker_innodb_recovery.sh

#!/bin/bash

# === 基础配置 ===
CONTAINER_NAME="mysql_docker"
MYSQL_USER="root"
MYSQL_PASS="your_pass"
BACKUP_DIR="./docker_mysql_recovery_$(date +%F_%H%M)"
RECOVERY_LEVEL=3   # 可调为 1~6

# === Step 1: 停止容器 ===
echo "[INFO] 停止容器 $CONTAINER_NAME..."
docker stop $CONTAINER_NAME

# === Step 2: 注入 innodb_force_recovery 配置 ===
echo "[INFO] 启动容器并设置恢复模式..."
docker commit $CONTAINER_NAME ${CONTAINER_NAME}_temp

docker run -d --name ${CONTAINER_NAME}_recovery \
  --rm \
  -e MYSQL_ROOT_PASSWORD=$MYSQL_PASS \
  --volumes-from $CONTAINER_NAME \
  ${CONTAINER_NAME}_temp \
  --innodb_force_recovery=$RECOVERY_LEVEL

# 等待 MySQL 启动
echo "[INFO] 等待 MySQL 启动..."
sleep 10

# === Step 3: 导出数据 ===
mkdir -p "$BACKUP_DIR"

echo "[INFO] 获取用户数据库列表..."
DBS=$(docker exec ${CONTAINER_NAME}_recovery \
  mysql -u$MYSQL_USER -p$MYSQL_PASS -Nse \
  "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('mysql','information_schema','performance_schema','sys');")

for DB in $DBS; do
  echo "[INFO] 导出数据库 $DB"
  docker exec ${CONTAINER_NAME}_recovery \
    mysqldump -u$MYSQL_USER -p$MYSQL_PASS \
    --single-transaction --skip-lock-tables --quick $DB \
    > "$BACKUP_DIR/$DB.sql"
done

# === Step 4: 停止容器并清理 ===
echo "[INFO] 停止应急容器..."
docker stop ${CONTAINER_NAME}_recovery

echo "[INFO] 删除临时镜像 ${CONTAINER_NAME}_temp"
docker rmi ${CONTAINER_NAME}_temp

echo "[OK] 导出完成,文件位于 $BACKUP_DIR"

四、目录结构(执行完毕后)

.
└── docker_mysql_recovery_2025-07-06_1450/
    ├── db1.sql
    ├── db2.sql
    └── ...

五、可选增强(进阶)

目标实现方式
📬 邮件通知导出状态mailxsendgrid API
🪄 自动压缩导出文件tar -czf backup.tar.gz *.sql
🐳 多容器批量处理使用 docker ps --filter "ancestor=mysql" 结合
📤 上传 OSS / S3使用 awsclicoscmd 工具
🔁 加入监控和容灾机制用 Prometheus + exporter 报警损坏日志

六、参考资料


七、注意事项

项目建议
RECOVERY_LEVEL ≥ 4严禁写操作,导出后要重建数据
备份导出的 .sql 文件可用 diff 验证完整性
修改配置后恢复正常模式重新启动容器 + 删除临时参数
不推荐长时间运行恢复模式容器会影响 buffer pool/日志行为

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

发表回复 0

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