Home » Uncategorized » MySQL借助ibd文件恢复数据技巧

MySQL借助ibd文件恢复数据技巧

磁盘坏道、断电等意外不是常态,但遇上了就足够你“惊心动魄”!如果是数据库损坏造成的数据丢失,Binlog也不可用了,怎么办?为了在短时间内无损恢复数据以保证业务稳定性,除了利用binlog,我们还修炼了一招新的恢复技能!

工具/原料

借助ibd文件恢复数据

  1. 首先检查数据库环境,是否开启了独立表空间,如果已经开启的话,那恭喜你,有很大的机会可以恢复全部数据。我们可以依赖每个数据库目录下的frm和ibd文件来实现数据恢复,一般来说如果使用了InnoDB但没开启独立表空间的话,所有的数据库表信息和元数据都会写入ibdata文件里,这样长久运行的话,ibdata文件会变得越来越大,数据库性能下降。InnoDB提供了开启独立表空间参数,可以让数据独立存放起来,这样子ibdata文件只用于存放一些引擎相关的索引信息,实际的数据写入到独立的frm和ibd文件里。

    好,有了frm和ibd文件,我们可以开始尝试数据恢复了,他的过程比binlog还原既惊险又有趣!首先我们来看一下关于ibd和frm的说明:

    .frm文件:保存了每个表的元数据,包括表结构的定义等,该文件与数据库引擎无关。

    .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per_table = 1)产生的存放该表的数据和索引的文件。

    我们都知道,对于InnoDB的数据库,如果不把整个数据目录拷贝,只拷贝指定数据库目录到新的实例下,数据库是认不出来的。那么如何根据这两个文件还恢复数据库呢?

  2. 由于ibdata文件上存放了一些关于引擎的索引信息,ibdata文件损坏导致表名索引丢失而无法启动。那么我们可以先把原来旧的整个数据目录改名备份,然后重新初始化数据库生成新的ibdata文件,然后重新创建原有的数据库以及对应的表,最后把备份的表空间id号改为新建的表空间id号(ibdata文件里有每个表唯一的表空间索引id,该id由创建新表的数量依次递增),这样就可以恢复原来的数据库了。举个例子:库名:test_restore表结构:db_struc.sql表文件:G_RESTORE.ibd、G_RESTORE.frm

  3. 创建新库,导入表结构

    #mysql -uroot –p****  -e “create database test_restore”

    #mysql -uroot –p****  test_restore < db_struc.sql

  4. 查看并修改test_restore库中表在新实例中的id

    #vim -b /data/database/mysql/test_restore/G_RESTORE.ibd

    直接打开为乱码,转成16进制查看。Vi中执行  :%!xxd 转化为16进制。结果为 :

    MySQL借助ibd文件恢复数据技巧
  5. 如上图所示。G_RESTORE表在mysql数据库中的id为00fe。

    修改备份的G_RESTORE.ibd文件。操作同上,注意需先备份。

    #cp G_RESTORE.ibd{,_back}

    #vim -v G_RESTORE.ibd

    将011b修改为00fe 。注意。修改完成后需要在vim中先执行 :%!xxd  -r

    再wq 保存退出文件。不然保存到的是16进制查看的结果。

    MySQL借助ibd文件恢复数据技巧
  6. 将修改好的G_RESTORE.ibd 替换掉新数据库中的G_RESTORE.ibd文件。

    关于ibdata表id的解释如下图:

    参考官方文档解释,每个表空间分配了4个字节存储了表空间id信息,最后偏移量地址为38。还有一组预留的表空间id,同样是4个字节,最后偏移量地址为42。

    MySQL借助ibd文件恢复数据技巧
  7.  验证并还原mysql数据

    关闭mysql。修改my.conf。innodb_force_recovery=6

    innodb_purge_threads=0

    启动数据库。如果不修改。数据库会认为G_RESTORE已被损坏。

    Select 一下,即可查看到还原结果,但此时插入数据会报错,应尽快将数据dump出来 ,导回原来的实例中。

    导出数据,再导入数据,恢复完毕!

    #mysqldump -uroot –p****** test_restore > test_restore.sql

    #mysql -uroot –p****** test_restore < test_restore.sql

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*