mysql innodb 从 ibd 文件恢复表数据
最近内部的 mysql 数据库发生了一件奇怪的事,其中有一个表 users625 突然出现问题,
所有对它的操作都报错误 数据表不存在
。
mysql> select count(*) from users625;
ERROR 1146 (42S02): Table 'km8.users625' doesn't exist
show tables
它还显示在列表里,在 mysql 数据目录中也可以找到对应的表文件,也没有
进行过删除操作,突然出现这样的错误非常奇怪。
内部运行环境:
名称 | 值 |
---|---|
OS | Debian Squeeze x64 |
mysql 版本 | 5.1 |
mysql 引擎 | innodb |
发生了什么
突然出现这种情况,第一反应必定是想办法将表中的用户数据找回,但是目前发生问题的情况与原因都不明晰,
不能轻举妄动。
查看 mysql 日志,在操作出错的时候,日志这样显示:
mysqld: 180926 11:10:53 InnoDB: cannot calculate statistics for table km8/users625
mysqld: InnoDB: because the .ibd file is missing. For help, please refer to
mysqld: InnoDB: http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html
mysqld: 180926 11:10:53 [ERROR] MySQL is trying to open a table handle but the .ibd file for
mysqld: table km8/users625 does not exist.
mysqld: Have you deleted the .ibd file from the database directory under
mysqld: the MySQL datadir, or have you used DISCARD TABLESPACE?
mysqld: See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html
mysqld: how you can resolve the problem.
其中提到3个可追溯的点:
- ibd file
- DISCARD TABLESPACE
- http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html
了解这3点提到的内容,应该对判断情况有很好的帮助。
ibd file
日志中提问,是否丢失了 ibd 文件?先到 mysql 数据目录下查找,
.
├── ibdata1
├── .......
├── .......
└── km8
├── ............
├── ............
├── users625.frm
├── users625.ibd
├── ............
└── ............
users625 的 ibd 文件是存在的,与之一起的还有文件 users625.frm 。
根据官方文档对 frm 文件的描述,frm 文件是用来保存 table 表结构(即 table 的定义)的,无论使用什么存储引擎。
与之相对的,ibd 文件是用来存储表数据(即行数据)的,通常情况下,所有数据都会存储在系统的 ibd 文件,
但是当开启选项 innodb_file_per_table 的时候,每个表的数据会使用单独的 ibd 文件来存储。
当前的 mysql 就开启了这个选项,
[mysqld]
innodb_file_per_table=1
目前 frm 与 ibd 文件都存在,从中恢复数据便存在一些希望。
DISCARD TABLESPACE
日志中提到的 DISCARD TABLESPACE
其实是在猜测导致 ibd 文件丢失的原因,因为它会删除相应 table 的 ibd 文件(所谓 tablespace)。
> ALTER TABLE km8.users625 DISCARD TABLESPACE;
底层的 users625.ibd 文件就会被删除,丢失所有表数据。
根据目前情况来看, ibd 文件还存在,所以它不是导致错误的原因。
trouble shooting doc
日志中提到的参考链接,其中列举了多种情况,和当前问题相关的是一个子链接,
按照它提供的方法,尝试进行数据恢复。
数据恢复
官方文档提到的恢复数据的方法,思路很清晰:
- 启用相同版本的 mysql 实例(启用选项 innodb_file_per_table)
- 建立同样结构的数据表
- 替换 ibd 文件(保持文件权限一致)
- 导入 ibd 文件中的数据
- 使用 mysqldump,导出数据
- 将导出的数据导入原数据库
我按照这种方式尝试恢复数据,并不是那么顺利:
如何获得 table 表结构?
在第2步,需要建立同样结构的数据表,目前只有 frm 和 ibd 文件,怎么样得到 create table
命令?
根据底层数据存储的理解,table 表结构存储在 frm 文件中,而目前已经有相应的方法从中提取出 create table
命令,
这样就可以用于在新的 mysql 实例中建立 table 。
tablespace id 不对应?
在第4步,尝试导入数据的时候,
> ALTER TABLE km8.users625 IMPORT TABLESPACE;
ERROR 1030 (HY000): Got error -1 from storage engine
总是出现失败,同时在 mysql 新实例的日志中发现这样的错误:
mysqld: InnoDB: Error: tablespace id in file './km8/users625.ibd' is 18446744073709551615, but in the InnoDB
mysqld: InnoDB: data dictinary it is 1.
原来在内部,ibd 文件本身有一个 id,必须和 mysql innodb 内部的 table 元数据相对应,才可以进行导入。
根据错误信息搜索到一篇文章,其中提到两种办法:
- 重复建表,因为 mysql 内部的 tablespace id 是累计递增的,预先建立 (18446744073709551615 - 1)张表,再建立
users625 表,就可以对应 id,并进行导入。 - 修改 ibd 文件,因为 tablespace id 存储于 ibd 文件,找到它并将其修改为 1,使之与内部的 id 对应,就可以进行导入。
考虑第 1 种方法,要预先建立上亿张空表?!这根本不可能。
于是尝试第 2 种方法,研究 ibd 的文件格式,修改对应 id。
用二进制编辑器打开 users625.ibd 文件,
18:26:08 UTC - mysqld got signal 6. This could be because you hit a bug. It is also possible that this
binary or one of the libraries it was linked against is corrupt, improperly built or misconfigured.
This error can also be cuased by malfunctioning hardware.
不敢相信自己的眼睛,居然有错误 log 在二进制文件里?!ibd 的文件格式可没有这么说明过。
随便找一个邻居表正常的 ibd 文件作对比,
看来是出现了 bug ,崩溃的环境直接将数据文件给毁了,这也解释了为什么 tablespace id 会那么大,因为 log
覆盖了原本的 id 字段,使 mysql 解读出了一个好笑的数字。
暂时放弃
这种情况下,还没有办法将数据恢复回来,只能暂时将表删除,新建空表,保证上层应用程序可以运行。
将 ibd 文件备份下来,看后续还没有其它的办法将其恢复。
检测所有 table 状态
当前只发现一个出现问题的 table ,可能同时也有其它的 table 出现问题。对此需要做一个全面的检测,
检测有没有其它的表受到牵连。
$ mysqlcheck --all-databases
写在最后
数据库的备份是非常重要的!直接导入备份数据,是解决问题最保险最便捷的办法。
如果没有备份,遇到 bug 丢失数据,只能怪时运不济。
同时数据库也最好选择稳定的版本,降低出现 bug 的概率。
mysql innodb 从 ibd 文件恢复表数据的更多相关文章
- MySQL 利用frm文件和ibd文件恢复表结构和表数据
文章目录 frm文件和ibd文件简介 frm文件恢复表结构 ibd文件恢复表数据 通过脚本利用ibd文件恢复数据 通过shell脚本导出mysql所有库的所有表的表结构 frm文件和ibd文件简介 在 ...
- MySQL innodb引擎下根据.frm和.ibd文件恢复表结构和数据
记录通过.frm和.ibd文件恢复数据到本地 .frm文件:保存了每个表的元数据,包括表结构的定义等: .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per ...
- mysql5.7根据.frm和.ibd文件恢复表结构和数据
一.恢复表结构 1.环境:Windows .mysql5.7:首先创建一个数据库,可以通过navicat来创建: 2.使用当前创建的数据库:use ww; 3.随意创建一张表,但是这张表的名字 ...
- mysql数据恢复:.frm和.ibd,恢复表结构和数据
mysql数据恢复:.frm和.ibd,恢复表结构和数据 一.恢复表结构 二.恢复表数据 相关内容原文地址: CSDN:她说巷尾的樱花开了:mysql根据.frm和.ibd文件恢复表结构和数据 博客园 ...
- 通过.frm表结构和.ibd文件恢复数据
整个恢复过程其实可以总结为下面几步: (1):恢复表结构 (2):复制出来创建表的sql语句 (3):恢复表数据(在恢复表数据的时候,首先需要解除当前创建的表与默认生成的.ibd文件间的关系,接着将要 ...
- mysql通过frm+ibd文件还原data
此方法只适合innodb_file_per_table = 1 当误删除ibdata 该怎么办? 如下步骤即可恢复: 1.准备工作 1)准备一台纯洁的mysql环境[从启动到现在没有 ...
- mysql 之 frm+ibd文件还原data
此方法只适合innodb_file_per_table = 1 当误删除ibdata 该怎么办? 如下步骤即可恢复: 1.准备工作 1)准备一台纯洁的mysql环境[从启动到现在 ...
- Oracle恢复表数据
Oracle恢复数据 在oracle 10g以及之后的版本,提供了回收站的机制,为了防止误操作将表数据清空而有回收机制. 换句话说,我们删除的表不会立马消失,而是进入回收站.下面我们可以查看回收站 查 ...
- mysql: 关于MySQL InnoDB锁行还是锁表?
baidu zone - 关于MYSQL Innodb 锁行还是锁表,深入讲解
随机推荐
- OpenCV2马拉松第2圈——读写图片
收入囊中 用imread读取图片 用nameWindow和imshow展示图片 cvtColor彩色图像灰度化 imwrite写图像 Luv色彩空间转换 初识API 图像读取接口 image = im ...
- js(window.open)浏览器弹框居中显示
<span style="background-color: rgb(204, 204, 204);"><html> <meta name=" ...
- 创建一个接口Shape,其中有抽象方法area,类Circle 、Rectangle实现area方法计算其面积并返回。又有Star实现Shape的area方法,其返回值是0,Star类另有一返回值boolean型方法isStar;在main方法里创建一个Vector,根据随机数的不同向其中加入Shape的不同子类对象(如是1,生成Circle对象;如是2,生成Rectangle对象;如是3,生成S
题目补充: 创建一个接口Shape,其中有抽象方法area,类Circle .Rectangle实现area方法计算其面积并返回. 又有Star实现Shape的area方法,其返回值是0,Star类另 ...
- iOS下微信语音播放之切换听筒和扬声器的方法解决方案
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; //建议在播放之前设置yes,播放结束设置NO,这个功能是开启红外感应 // ...
- Scrapy-从数据库取出IP并判断是否可用
import pymysql import requests conn = pymysql.connect(host="localhost",user="root&quo ...
- 目标反射回波检测算法及其FPGA实现 之二:互相关/卷积/FIR电路的实现
目标反射回波检测算法及其FPGA实现之二: 互相关/卷积/FIR电路的实现 前段时间,接触了一个声呐目标反射回波检测的项目.声呐接收机要实现的核心功能是在含有大量噪声的反射回波中,识别出发射机发出的激 ...
- 20145209刘一阳《JAVA程序设计》第七周课堂测试
第七周课堂测试 1.命令"CREATE DATABASE "用来创建一个数据库.(A) A .true B .false 2.以下不属于驱动的四种类型的是(C) A .JDBC-O ...
- Noip前的大抱佛脚----数论
目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...
- Linux命令学习笔记1
1.Linux命令学习 2.Mkdir /data -创建文件夹 在/下创建文件夹 data 3.Cd -目录切换 列如cd / 4.Touch /data/1 ...
- 2-5 re模块练习题
1 练习: 1.验证手机号是否合法 2.验证邮箱是否合法 3.开发一个简单的python计算器,实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2 ...