背景:
前段时间,磁盘格式化,忘了吧数据库备份。而且格式化后有写入数据,导致恢复出来的数据库文件有些许损坏,数据库无法正常启动。
适用场景:
必须满足的条件:
1、本方法只针对采用独立表空间方式存储数据的Mysql数据库的恢复。
2、无论如何,ibdata1文件必须存在。
3、本方法适用单个表数据恢复,你可以不知道整个数据库的所有表定义,但必须知道你要提取数据的表的定义,凭记忆在其他数据库重新建一个表也行。
可以应对以下场景:
1、数据库服务无法启动。
2、服务可以启动(或通过配置innodb_force_recovery方式启动),但关键数据库或数据表无法打开。
3、数据库表结构丢失,只剩下ibdata1及其同类型文件。
前言:
1、如果因意外断电或其他情况,导致Mysql无法正确启动,可尝试配置innodb_force_recovery,忽略启动时的一些常规检测,强行启动。
2、如果表结构和数据文件都完整而无法正常启动数据库的,尽可能使用常见的简单的修复方法修复。本方法略微复杂些,也是万般无奈时才会使用。
思路:
MySql是开源的,其底层的数据存储和查询方式是公开的。所以,可以按照Mysql查询数据的方式进行提取数据。具体流程如下:
1、获取要提取数据的表的表定义。原数据库里的表定义也好,自己又凭记忆创建的也罢,只要有就好,不过尽量准确,不然可能会因类型转换错误导致乱码。
2、提取需要的页。InnoDB页的默认大小是16K,每个页属于一个特定表中的一个特定的index。也就是你的表的数据存储在很多页中,每个页存16k的数据,你需要找到你需要的数据存储在哪些页里。这里如何获取可分两种情况,一种是Mysql服务可以启动,一种是无法启动。具体方法下面介绍。
3、将得到的页的数据按照第一步中取到的表定义转换成对应的数据记录,如果你的表数据分布在N多页中,可以先合并这些页,在提取数据。
4、数据拿到,下一步如何操作就可以跟进实际情况做了,重建数据库,一个表一个表的恢复也好,就只要这一个表的数据也罢。
具体步骤:
思路如上,由于我们不是很了解Mysql的存储查询原理,只能借助专业的工具。也就是:Percona Data Recovery Tool for InnoDB。
具体如何使用,可以参考:http://www.cnblogs.com/panfeng412/archive/2012/03/04/data-recorvery-of-mysql-innodb.html
不启动服务提取需要的页:
不过上面提到的博客中获取页的方式是在数据库服务尚能启动的情况。而当数据库服务无法启动时,只要你对你的数据足够了解,其实也是可以提取到数据所在的page的。
具体如何在离线的情况下获取页,可参考如下:https://www.percona.com/docs/wiki/innodb-data-recovery-tool_mysql-data-recovery_advanced_techniques.html
简单说下我用的一种,找一个基本唯一的数据关键字,通过遍历所有页的方式,找到对应的页。
在使用Percona Data Recovery Tool for InnoDB工具时,首先会将ibdata1文件进行切分页,切出来的页会分布在N多文件夹中,每个文件夹中的页都属于同一个表。所以,只要你通过关键字的方式,锁定一个page页,那么它所在的文件夹下的所有页都是这个表的数据,基本上就可用拿到该表的所有数据了。
Linux下,使用命令:
$ grep -r "你的关键字" pages-1217332715/
这里的 pages-1217332715/是切分页时生成的目录,替换成你自己的就可以,该命令会对该文件夹下所有文件以及子文件夹下的文件进行遍历,找出匹配到的文件。
之后再结合上文提到的博客里的方法合并多个页,再提取数据就可以了。
其他的方法,我没试,可以自行试试。