Inno_space 处理 MySQL ibd 损坏的页

  • Inno_space 是C++开发的工具,可以直接访问 ibd 文件,也可以修复损坏的页面

安装 inno_space

1
2
3
git clone git@github.com:baotiao/inno_space.git
cd inno_space
make

创建测试表并备份数据

  • MySQL 创建测试表 testdb.sales,写入部分测试数据
  • 进入 MySQL data 目录,备份当前 ibd 文件
1
2
3
cd mysql5.7/mysql_data/data/testdb
mkdir -p ~/bk/57
cp sales.* ~/bk/57/
  • 查看表行数
1
2
3
4
5
6
mysql> select count(*) from sales;
+----------+
| count(*) |
+----------+
|    20000 |
+----------+

模拟数据页损坏

  • ibd 文件是 16进制,需以二进制打开,转成16进编辑,之后再转为二进制保存
  • 安装 xxd
1
apt -y install xdd
  • 编辑 xxd 文件,大概文件内容如下
1
vim -b sales.ibd
  • vim 内转成十六进制编辑,转成十六进制文件内容大概如下
1
2
# vim 内将文件转为16进制
:%!xxd
  • 在文件中间部分,随机更改部分内容
1
2
3
4
# 改前
90004 0015f930: 8000 3936 8000 3937 8000 3938 8fd1 2900  ..96..97..98..).
# 改后
90004 0015f930: 8001 3937 8000 3937 8000 3938 8fd1 2900  ..96..97..98..).
  • 转为二进制保存
1
2
# vim 将文件从十六进制转成二进制保存
:%!xxd -r
  • 重启实例,关注日志,关注error日志里面的错误页相关日志
    • 由报错日志可知,错误页87
1
2024-09-13T11:52:20.312065+08:00 0 [ERROR] InnoDB: Database page corruption on disk or a failed file read of page [page id: space=57, page number=87]. You may have to recover from a backup.

故障处理

删除损坏的页

1
2
3
4
# 删除坏页
./inno -f /app/xiang/mysql5.7/mysql_data/data/testdb/sales.ibd   -d 87
# 更新校验和
./inno -f /app/xiang/mysql5.7/mysql_data/data/testdb/sales.ibd   -u 87
  • 查看当前行数
1
2
3
4
5
6
mysql> select count(*) from sales;
+----------+
| count(*) |
+----------+
|    19736 |
+----------+
  • 检查 error 日志已无报错信息

参考